主要内容:
1.生成JWT工具类
2.配置过滤器
3.注册过滤器
4.配置全局异常类
5.测试
引入JWT依赖:
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
本项目中会用到 fastjson工具依赖,用来将Result 响应结果对象转化成 json对象返回给前端
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
1.生成JWT工具类
@Data
@Component
public class JwtUtils {
private String secretId = "are3gh3456jint765ydh45mxj7ie5j6i";
private long expire = 7;
private String header = "token";
// 根据用户名生成jwt
public String createToken(String username) {
// 1.定义header
Map headerMap = new HashMap();
headerMap.put("alg", SignatureAlgorithm.HS256.getValue());
headerMap.put("typ", "JWT");
// 2.定义payload
Date nowDate = new Date();
Date expireDate = new Date(nowDate.getTime() + expire * 1000 * 24 * 60 * 60);
// 3.生成token
return Jwts.builder()
.setHeaderParams(headerMap)
.setSubject(username)
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS256, secretId)
.compact();
}
// 解析jwt
public Claims getToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secretId)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
return null;
}
}
// 验证token是否过期
public boolean isTokenExpired(Date expirationTime) {
return expirationTime.before(new Date());
}
// 获取token 过期时间
public Date getExpirationDateFromToken(String token) {
return getToken(token).getExpiration();
}
// 获取用户名
public String getUsernameFromToken(String token) {
return getToken(token).getSubject();
}
// 获取jwt发布时间
public Date getIssuedAtDateFromToken(String token) {
return getToken(token).getIssuedAt();
}
}
2.配置过滤器
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Resource
private JwtUtils jwt;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1.地址过滤
String url = request.getRequestURI();
if (url.contains("/login")) {
log.info("登录请求,放行");
return true;
}
// 2.token验证
// 3.获取请求头中的令牌
String token = request.getHeader(jwt.getHeader());
// 4.判断令牌是否存在
if (!StringUtils.isEmpty(token)) {
// 5.令牌不存在
log.info("请求头token为空,返回");
Result loginerr = Result.error("NOT_NOLOGIN");
// 把对象转换为JSON返回
String nologin = JSONObject.toJSONString(loginerr);
response.getWriter().write(nologin);
return false;
}
// 6.令牌存在,但是令牌可能过期
Claims claims = null;
try {
claims = jwt.getToken(token);
if (claims == null || jwt.isTokenExpired(claims.getExpiration())) {
throw new SignatureException(jwt.getHeader() + "token失效");
}
} catch (Exception e) {
throw new SignatureException(jwt.getHeader() + "tokne失效");
}
//设置identityId 用户身份ID
request.setAttribute("identityId",claims.getSubject());
return true;
}
}
3.注册过滤器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
}
}
4.配置全局异常类
@RestControllerAdvice
public class GlobalException {
@ExceptionHandler(value = {SignatureException.class})
@ResponseBody
public Result authorizationException(SignatureException e) {
return Result.error( "error");
}
}
5.测试
@RestController
public class loginController {
@Resource
private JwtUtils jwtUtils;
@PostMapping("/login")
public Result login(String username, String password) {
JSONObject json = new JSONObject();
// 模拟从数据库中查询用户名,和密码
String user = "老朱";
String token = jwtUtils.createToken(user);
if (!StringUtils.isEmpty(token)) {
json.put("token", token);
}
return Result.success(json);
}
// 请求其它接口
@PostMapping("/info")
public Result info() {
return Result.success("info");
}
// 将token放到请求头中 来请求
@GetMapping("/getuser")
public Result getUserInfo(HttpServletRequest request) {
String username = jwtUtils.getUsernameFromToken(request.getHeader("token"));
return Result.success(username);
}
}