JSON Web Token是目前最流行的跨域认证解决方案,适合前后端分离项目通过Restful API进行数据交互时进行身份认证

java 的 JWT 有效期 jwt设置永久有效_数据

**

关于有效期

**
由于jwt是直接给用户的,只要能验证成功的jwt都可以被视作登录成功,所以,如果不给jwt设置一个过期时间的话,用户只要存着这个jwt,就相当于永远登录了,而这是不安全的,因为如果这个令牌泄露了,那么服务器是没有任何办法阻止该令牌的持有者访问的(因为拿到这个令牌就等于随便冒充你身份访问了),所以往往jwt都会有一个有效期,通常存在于载荷部分,下面是一段生成jwt的java代码:

return JWT.create().withAudience(userId)
                .withIssuedAt(new Date())        <---- 发行时间
                .withExpiresAt(expiresDate)     <---- 有效期
                .withClaim("sessionId", sessionId)
                .withClaim("userName", userName)
                .withClaim("realName", realName)
                .sign(Algorithm.HMAC256(userId+"HelloLehr"));

在实际的开发中,令牌的有效期往往是越短越安全,因为令牌会频繁变化,即使有某个令牌被别人盗用,也会很快失效。但是有效期短也会导致用户体验不好(总是需要重新登录),所以这时候就会出现另外一种令牌—refresh token刷新令牌。刷新令牌的有效期会很长,只要刷新令牌没有过期,就可以再申请另外一个jwt而无需登录(且这个过程是在用户访问某个接口时自动完成的,用户不会感觉到令牌替换),对于刷新令牌的具体实现这里就不详细讲啦(其实因为我也没深入研究过XD…)

**

对比Session

**
在传统的session会话机制中,服务器识别用户是通过用户首次访问服务器的时候,给用户一个sessionId,然后把用户对应的会话记录放在服务器这里,以后每次通过sessionId来找到对应的会话记录。这样虽然所有的数据都存在服务器上是安全的,但是对于分布式的应用来说,就需要考虑session共享的问题了,不然同一个用户的sessionId的请求被自动分配到另外一个服务器上就等于失效了

而Jwt不但可以用于登录认证,也把相应的数据返回给了用户(就是载荷里的内容),通过签名来保证数据的真实性,该应用的各个服务器上都有统一的验证方法,只要能通过验证,就说明你的令牌是可信的,我就可以从你的令牌上获取你的信息,知道你是谁了,从而减轻了服务器的压力,而且也对分布式应用更为友好。(毕竟就不用担心服务器session的分布式存储问题了)

**

整合Springboot 导入java-jwt包

**
pom.xml里写入

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

token的生成

/**
 * 生成token
 * @param userId
 * @param userName
 * @return
 */
public String createToken(String userId,String userName){
    Calendar nowTime = Calendar.getInstance();
    nowTime.add(Calendar.MINUTE,30);
    Date expiresDate = nowTime.getTime();
    return JWT.create().withAudience(userId)   //签发对象
            .withIssuedAt(new Date())    //发行时间
            .withExpiresAt(expiresDate)  //有效时间
            .withClaim("userName", userName)    //载荷,随便写几个都可以
            .sign(Algorithm.HMAC256(userId+"HelloLehr"));   //加密
}

token的验证

/**
 * 验证token是否合法
 * @param token
 * @param secret
 * @return
 */
public boolean verifyToken(String token, String secret){
    DecodedJWT jwt = null;
    try {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret+"HelloLehr")).build();
        jwt = verifier.verify(token);
    } catch (Exception e) {
        //效验失败
        return false;
    }
    return true;
}

使用

@RequestMapping("/w1")
public Object w1(){
    String token = createToken("10001", "洪华宇");

    return token;
}
@RequestMapping("/w2")
public Object w2(String token, String secret){
    boolean verifyToken = verifyToken(token, secret);
    if(verifyToken){
        return "合法";
    }else {
        return "非法";
    }
}