JWT实现登录权限验证逻辑
1.登录验证流程(时序图)
2.JWT认证操作
(1)首先是创建JWT:
数字签名(Digital Signature): 数字签名的主要用途也是用于身份认证,在服务器你需要指定一个签名算法。(HS256,RS256等)
创建 JWT(在这里使用HS256算法, 私匙使用固定秘钥),其中的secretKey此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个,HS256算法使用同一个secret_key进行签名与验证(对称加密)。一旦 secret_key 泄漏,就毫无安全性可言了。因此HS256算法更适合在单体架构上使用,尽量不用在分布式架构使用该加密算法
下面给一段创建JWT的java代码示例
/**
* 生成jwt
*
* @param secretKey jwt秘钥
* @param ttlMillis jwt过期时间(毫秒)
* @param claims 设置的信息
* @return
*/
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
// 指定签名的时候使用的签名算法
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 于计算 JWT 的过期时间
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
// 设置jwt的body
JwtBuilder builder = Jwts.builder()
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后, 就是覆盖了那些标准的声明的
.setClaims(claims)
// 设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
// 设置过期时间
.setExpiration(exp);
return builder.compact();
}
这段代码的返回值就是认证信息token,需要提交给前端服务器(浏览器,或者小程序),小程序储存起来每次发送请求时候携带认证信息
(2)解密token:
后端服务器在拦截器里获取请求的认证信息进行解密,进行令牌校验,校验完成才能执行请求逻辑
/**
* Token解密
*
* @param secretKey jwt秘钥
* @param token 加密后的token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
// 设置需要解析的jwt
.parseClaimsJws(token).getBody();
return claims;
}
拦截器部分代码:
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
// 1、 认证信息存储
。。。
//2、通过,放行
。。。
return true;
} catch (Exception ex) {
//3、不通过,响应401状态码
response.setStatus(401);
return false;
}
3.前端封装token
浏览器端(使用vue + ts):可以自定义axios对象,在登陆请求是利用浏览器提供的Storage对象存储认证信息
小程序端:自定方法发起请求,利用微信的getStorage&&setStorage方法存储认证信息