【java】使用jwt进行认证受权

传统的web应用使用session来维护用户与服务器之间的状态,用户提交用户名密码到服务器,服务器生成会话id,并将验证经过的用户信息存到session中(内存or数据库),会话id会写出到cookie。
用户登陆以后的操做,都会附带包含sessionId的cookie,服务器根据用户端传来的sessionId获取用户信息,会话的有效期,包括用户登出等操做都依赖对session的操做,以下图:
在这里插入图片描述
基于session的认证用户信息存在了服务端内存中,在分布式环境中session是须要同步的。出现了基于token的认证方式,其实本质和session没什么区别。用户提交登陆信息后,服务端验证经过后颁发令牌。
下图是以redis为例,将token和用户信息保存到redis,客户端再次访问服务端时,会携带token,服务端经过token获取用户信息。会话的有效期,用户的登出只须要操做redis中的token便可,以下图:
在这里插入图片描述
固然了,token自己也是能够包含一些用户非敏感信息减小查库,包含数字签名以防数据篡改,下面看下jwt(json web token)。java

从名称能够看出jwt仍是一个token,它有本身的规范,由标头.有效载荷.签名
组成。头用来描述散列算法,而后是用户数据,最后是一个数字签名。web

在这里插入图片描述
先来看下jwt的java实现。redis

dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.2</version>
</dependency>

使用jwt一般只须要两个步骤,1经过jwt来生成token,2验证token。算法

public class JwtUtil {
    private static final String SECRET = "t1o2k3e4n5_s9e8c7r6e5t";
    private static final String ISSUER = "star_jwt";
    public static String genJwt(Map<String, String> claims) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTCreator.Builder builder = JWT.create().withIssuer(ISSUER).withExpiresAt(DateUtils.addMinutes(new Date(),30));
            claims.forEach(builder::withClaim);
            return builder.sign(algorithm);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static Map<String, String> verifyToken(String token)  {
        Map<String, String> ret = Maps.newHashMap();
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
            DecodedJWT jwt =  verifier.verify(token);
            Map<String, Claim> map = jwt.getClaims();
            map.forEach((k,v)->ret.put(k,v.asString()));

       ret.put("exp",map.get("exp").asDate().toString());
        } catch (Exception e) {

            throw new RuntimeException(e);
        }
        return ret;
    }
}

以上就是一个jwt的简单示例,客户端携带token请求时,服务端能够校验jwt的签名及有效时间,校验经过则放行,不然拒绝请求。数据库

优势:
能够看到使用jwt自身就能够完成认证,能够减小资源链接,也能够避免跨域认证请求,自带信息也能够用于数据传递。
缺点:
能够看到一旦生成token,就没法回收,token的管理(刷新有效期&登出)须要其它补偿机制(如使用redis管理token);默认有效载荷只是通过base64编码,只是为了方便传输,并未加密(也能够自行加密),敏感数据不该该放到jwt中。json

以为有用,点个关注:
在这里插入图片描述跨域