1.使用jwt身份校验
1.1 Jwt的简单使用
1.引入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.测试
@Test
void contextLoads() {
Map<String, Object> Claims = new HashMap<>();
Claims.put("id", 1);
Claims.put("name", "tom");
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, "sanjin") //签名算法
.setClaims(Claims) //自定义内容(载荷)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) //设置有效期1h
.compact(); // 用于将 JWT 压缩为其最终的字符串表示形式。
System.out.println(jwt);
}
@Test
public void testParseJwt() {
Claims claims = Jwts.parser()
.setSigningKey("miyao") // 自己定义密钥
.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTY5OTk0MDc3MX0.lG-oXshhbsKvjEP24knidlkW_-TtJ1wZkNsMD-N-4w4")
.getBody();
System.out.println(claims);
}
1.2 创建jwt工具类
public class JwtUtil {
/**
* 生成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的body
JwtBuilder builder = Jwts.builder()
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
.setClaims(claims)
// 设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
// 设置过期时间
.setExpiration(exp);
return builder.compact();
}
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @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;
}
}
1.3 利用filter拦截请求
1.继承filter接口
@WebFilter(urlPatterns = "/*")
public class JwtFilter implements Filter {
2.重写过滤方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 判断登录url
String url = request.getRequestURL().toString();
if (url.contains("login")) {
log.info("登录操作放行");
filterChain.doFilter(servletRequest, servletResponse);
}
// 获取jwt
String token = request.getHeader("jwttoken"); // 自己定义
// 是否存在jwt
if (StrUtil.isBlank(token)) {
log.info("未携带token");
return;
}
Map<String, Object> map = null;
try {
map = JwtUtil.parseJwtToken(token);
} catch (Exception e) {
log.info("token解析失败,msg={}", e.getMessage());
throw new RuntimeException(e);
}
if (!CollectionUtil.isEmpty(map)) {
log.info("token校验通过用户id为:{}", map.get("id"));
filterChain.doFilter(servletRequest, servletResponse);
}
log.info("token校验不通过");
}
3.开启severlet支持
@ServletComponentScan
@SpringBootApplication
public class DayLearnApplication {
public static void main(String[] args) {
SpringApplication.run(DayLearnApplication.class, args);
}
}