JWT的生成及验证过程

在前后端分离的场景中,前后台主要用jwt交互,比如说前端发一个提交信息的请求,后台必须知道这个提交者的信息吧(提交者id),但为了使传输更安全,jwt包含了需要的用户信息以加密的方式传输以达到这个目的。

先看看jwt的定义,网上随处可见的:jwt全称Json Web Token,由三部分构成:头部(header)、载荷(payload, )、签证(signature).

传输信息用到的就是载荷:就是存放有效信息的地方,就是这样的键值对构成的Map对象:

iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
jwt用Claims对象来存自定义的信息(也是一个键值对的Map对象):当登录的时候,就把当前的用户的信息存进去,这里模拟一下(假如从数据库中获取了用户信息)
@ResponseBody
@RequestMapping("login.do")
public JsonAndModel sayHello(HttpServletRequest request, HttpServletResponse response) {
    Map<String,Object> claims = new HashMap<>();
    claims.put("username","wang");
    claims.put("userid",12);
    System.out.println(new Date().getTime() + "---start---");
    return JsonAndModel.builder(TokenUtil.tokens(claims)).build();
}
然后把信息存到一个map里面,通过工具生成token字符串返回给前台,当前台再次请求的时候就带上这个token,然后取参数验证。
package cn.wzy.util;
 
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.*;
 
/**
 * @author wzy
 * @Date 2018/4/6 14:00
 */
public class TokenUtil {
    private static Properties properties = new Properties();
    private static ResourceBundle resource = ResourceBundle.getBundle("database");
    public static Object getValue(String key) {
        return resource.getString(key);
    }
 
    public static String tokens(Map<String,Object> claims) {
        String SecretKey = (String) getValue("secretkey");
        //获取当前的时间
        Calendar calendar = Calendar.getInstance();
        Date date = new Date(System.currentTimeMillis());
        calendar.setTime(date);
        //向后退后的秒数
        int time = Integer.parseInt((String) getValue("millisecond"));
        calendar.add(Calendar.MILLISECOND, time);
        Date endTime = calendar.getTime();
        String issuer = (String) getValue("JWT_ISSUER");
        String aud = (String) getValue("JWT_AUD");
        JwtBuilder builder = Jwts.builder().setClaims(claims)
                .signWith(SignatureAlgorithm.HS256,SecretKey)
                .setClaims(claims)
                .setSubject((String)claims.get("username"))
                .setIssuedAt(new Date())
                .setExpiration(endTime)
                .setIssuer(issuer)
                .setAudience(aud);
        return builder.compact();
    }
 
    /**
     * 从jwt中获取用户信息
     * @param jsonWebToken
     * @return
     */
    public static Claims parseJWT(String jsonWebToken) {
        String secretKey = (String) getValue("secretkey");
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (Exception ex) {
            return null;
        }
    }
}
验证过程:把前端存到header里面的token解析成一个Claims对象获取参数验证(当时间过了设置的token失效时间,这个对象就失效为null,也就未登录)
@ResponseBody
@RequestMapping("checkOnlie.do")
public JsonAndModel check(HttpServletRequest request, HttpServletResponse response) {
    String claims = request.getHeader("claims");
    Claims info = null;
    if (claims != null) {
        info = TokenUtil.parseJWT(claims);
        System.out.println(info == null);
        System.out.println(new Date().getTime());
    }
    return JsonAndModel.builder(info).build();
}




猜你喜欢

转载自blog.csdn.net/qq_38089964/article/details/80803765