用户登录之后的操作,都会附带包含sessionId的cookie,服务器根据用户端传来的sessionId获取用户信息,会话的有效期,包括用户登出等操作都依赖对session的操作,如下图:----
基于session的认证用户信息存在了服务端内存中,在分布式环境中session是需要同步的。出现了基于token的认证方式,其实本质和session没什么区别。用户提交登录信息后,服务端验证通过后颁发令牌。下图是以redis为例,将token和用户信息保存到redis,客户端再次访问服务端时,会携带token,服务端通过token获取用户信息。会话的有效期,用户的登出只需要操作redis中的token即可,如下图:
当然了,token本身也是可以包含一些用户非敏感信息减少查库,包含数字签名以防数据篡改,下面看下jwt(json web token)。----
从名称可以看出jwt还是一个token,它有自己的规范,由标头.有效载荷.签名
组成。头用来描述散列算法,然后是用户数据,最后是一个数字签名。
----
先来看下jwt的java实现。
com.auth0java-jwt3.10.2
使用jwt通常只需要两个步骤,1通过jwt来生成token,2验证token。
JwtUtil String = String = String MapStringStringclaimsAlgorithm algorithm = Algorithm.JWTCreator.Builder builder = JWT..withIssuer.withExpiresAtDateUtils.Dateclaims.forEachbuilder::withClaimbuilder.signalgorithmException eRuntimeExceptioneMapStringStringString tokenMapStringStringret = Maps.Algorithm algorithm = Algorithm.JWTVerifier verifier = JWT.algorithm.withIssuer.buildDecodedJWT jwt = verifier.verifytokenMapStringClaimmap = jwt.getClaimsRuntimeExceptioneret
以上就是一个jwt的简单示例,客户端携带token请求时,服务端可以校验jwt的签名及有效时间,校验通过则放行,否则拒绝请求。
----优点:可以看到使用jwt自身就可以完成认证,可以减少资源连接,也可以避免跨域认证请求,自带信息也可以用于数据传递。
缺点:可以看到一旦生成token,就无法回收,token的管理(刷新有效期&登出)需要其它补偿机制(如使用redis管理token);默认有效载荷只是经过base64编码,只是为了方便传输,并未加密(也可以自行加密),敏感数据不应该放到jwt中。