jwt令牌的组成
1.Header:记录令牌类型,签名算法等,例如:{"alg":"HS256","type":"JWT"}
2.Payload(有效载荷),携带一些自定义信息,默认信息等,例如:{"id":"1","username":"Tom"}
3.Signature(签名):防止Token被篡改,确保安全性,将Header,Payload一并加入指定秘钥中,通过指定签名算法计算而来.
引入依赖
第一种
在这个版本中对签名长度有了一定的要求,必须要达到256个字节,如果你不想使用这么长的签名的话,可以使用第二种
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version></dependency><!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-gson</artifactId><version>0.11.5</version></dependency>
第二种
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
第二种不会爆长度错误
生成jwt令牌
传递的参数,签名,有效时间,携带的信息
1.签名算法用SignatureAlgorithm指定
2.有效荷载使用Map<String,Object>claim
3.指定签名字符串
java">/*** 生成jwt* 使用Hs256算法, 私匙使用固定秘钥** @param secretKey jwt秘钥* @param ttlMillis jwt过期时间(毫秒)* @param claims 设置的信息* @return*/public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {// 指定签名的时候使用的签名算法,也就是header那部分SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成JWT的时间long expMillis = System.currentTimeMillis() + ttlMillis;Date exp = new Date(expMillis);// 设置jwt的bodyJwtBuilder builder = Jwts.builder()// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setClaims(claims)// 设置签名使用的签名算法和签名使用的秘钥.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))// 设置过期时间.setExpiration(exp);return builder.compact();}
接下来是一个固定的格式使用builder中的setClaims或者addClaims添加信息,使用signWith传入连个参数,第一个是设置签名算法,第二个是设置秘钥.然后是过期时间.最后调用compact方法用于将builder转换成一个紧凑的字符串
解析jwt令牌
java"> public static Claims parseJWT(String secretKey, String token) {// 得到DefaultJwtParserClaims claims = Jwts.parser()// 设置签名的秘钥.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))// 设置需要解析的jwt.parseClaimsJws(token).getBody();return claims;}
传入秘钥和令牌就可以获得信息.
在苍穹外卖里整体流程是这样的
首先将一些固定信息定义在application.yml里
sky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: token
然后定义一个Jwtproperties类
java">@Component
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {/*** 管理端员工生成jwt令牌相关配置*/private String adminSecretKey;private long adminTtl;private String adminTokenName;}
@ConfigurationProperties(prefix = "sky.jwt")使用这个注解自动映射要注意变量名得是属性名去掉了"-"后的驼峰命名.
然后创建并使用
@Autowired private JwtProperties jwtProperties;
java">String token = JwtUtil.createJWT(
jwtProperties.getAdminSecretKey(),
jwtProperties.getAdminTtl(),
claims);