jwt实战

jwt的作用:【也就是Json web token】eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9.49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY
我们可以看出他有三个部分组成的字符串,第一部分为 header【一般包含header的声明类型和指定加密算法HS256】 第二部分为 payload 第三部分为签名验证 signature
首先对jwt有个大体的框架认识,过多的原理知识我就不在此介绍了,我们可以简答的划分为 jwtPayload【信息载体或者说是信息主体】,jwtSetting【配置信息 可能包含一些secretKey authsalt tokenHeader...】,jwtType【可理解为角色类型或者信息加密类型】。
其中jwtPayload信息载体class中可以设置如下属性  id,jwtType,name,如下:
{
  “id”:“1222”,
  “name”:“人人”,
  “jwtType”:“student”
}
payload的又可仔细划分为四个三个小模块
· 标准中注册的声明  【iss:jwt签发者。sub:jwt所面向的用户。 aud:jwt所面向的接收者。 exp:jwt的过期时间 这个时间必须要大于签发的时间。iat:jwt签发时间,jti:jwt的唯一身份标识,主要用来作为一次性的token 放攻击】
· 公共的声明:  声明一下公共信息 但是非敏感信息 因为base64加密是对称加密 一般添加用户信息或者业务信息
· 私有的声明:  提供者和消费者共同定义的声明。也是不建议声明敏感信息
如果将上面的jwtpayload进行base64机密后得到字符串的第二部分。
jwt的第三个部分是签名,是由header经过base64加密和jwtpayload经过base64加密然后用.号连接在加上secretKey,在通过在header中声明的加密算法来进行加密,得到jwt的第三个部分。
jwtSetting属性为secretKey为随机生成的字符串作为加密的秘钥 tokenheader和Authsalt可以是自己设定为主,可在application.properties或application.yml中指定。
jwtType需要根据自己需求来确定角色类型,举个例子 游客 会员 管理员......一般设置成枚举类。


然后就到了对应的各种setter和getter方法 其中生成secretkey的随机字符串可用使用Apache的Commons-lang3 包的工具类来解决
RandomStringUtils.randomAlphanumeric(int length);


@PostConstruct
public void poplateSecretKey(){
  this.secretKey = RandomStringUtils.randomAlpanumeric(32);
}
####################################################我是分割线###################################################
核心的jwtSercice算法如下:
@Service
public class JwtService{
  
   @Autowired private JwtSettiong jwtConfig;
//  将token信息转换为jwt中的payload载体信息 如果successful 将返回的是id name type的详细信息
   public Claims parseToken(String token){
        try{
           Claims body = Jwts.parser().setSigningKey(jwtConfig.getSecretKey()).parseClaimsJws(token).getBody();
           return body;
      }catch(JwtException e){
         throw new JwtException("认证信息错误");
    }     
 }


    //  信息的加密和转化过程 也就是就是生成token的过程
    public String generateToken(JwtPayload data){
       // 设置过期时间
       long now = new Date().getTime();
       Date exp = new Date(now + jwtConfig.getEcpiretion() * 60 * 1000);
       Claims claims = Jwts.claims().setSubject(assembleSubject(data)).setIssuedAt(new Date()).setExpiration(exp); //  设置jwt的签发时间和过期时间
       claims.put("id",data.getId());
    return Jwts.builder().setClaims(claims).setSignWith(SignatureAlgorithm.HS256,jwtConfig.getSecreteKey()).compact();   
  }


   private String assembleSubject(jwtPayload data){
    return String.format("%s:::%s",data.getType().name(),data.getName());   //  把data作为一个转化为一个新的字符串  %s:::%s  作为subject来进行token的生成
 }


//  工具方法 验证jwt token的类型是否正确


public boolean isRightType(Claims claims,JwtType jwttype){
  if(claims == null || jwttype == null){
    return false;
}


jwtType role = JwtType.valueOf(claims.getSubject().split(":::")[0]);
return jwttype==role;
}
}




以后就是如何生成token和利用token获取用户信息的算法逻辑,如果需要更为详细的用法,需要我们使用实际操作,包含一些操作,利用Filter或者拦截器进行。

你可能感兴趣的:(工作问题归纳)