(1)导入依赖(jwt)
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
(2)token工具类
@Slf4j
@Component
@Data
@ConfigurationProperties(prefix = "blog.jwt")
public class JWTUtils {
private long expire;
private String secure;
private String header;
//生成jwt
public String createToken(String username){
Date nowTime = new Date();
Date expireTime = new Date(nowTime.getTime() + 1000 * expire);
return Jwts.builder()
//token类型
.setHeaderParam("typ","JWT")
.setSubject(username)
.setIssuedAt(nowTime)
.setExpiration(expireTime)
.signWith(SignatureAlgorithm.HS512,secure)
.compact();
}
//解析jwt
public Claims getClaimsByToken(String jwt){
try {
return Jwts.parser()
.setSigningKey(secure)
.parseClaimsJws(jwt)
.getBody();
} catch (Exception e) {
return null;
}
}
/**
* 判断是否token过期
* @param claims
* @return
*/
public boolean isTokenExpired(Claims claims){
return claims.getExpiration().before(new Date());
}
}
//创建token
String token = jwtUtils.createToken(authentication.getName());
//将token放在请求头中,前端获取
httpServletResponse.setHeader(jwtUtils.getHeader(),token);
(4)关闭session
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
(5)实现过滤器JWTFilter extends BasicAuthenticationFilter
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
//获得请求中的token
String jwt = request.getHeader(jwtUtils.getHeader());
//token不存在,匿名访问,放行
if(jwt==null||jwt==""){
chain.doFilter(request,response);
return;
}
Claims claims = jwtUtils.getClaimsByToken(jwt);
//获取token信息
if(claims==null){
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSON.toJSONString(new Result(false, StatusConst.TOKEN_ERROR, "token异常!")));
return;
}
if(jwtUtils.isTokenExpired(claims)){
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSON.toJSONString(new Result(false, StatusConst.TOKEN_EXPIRED, "用户身份过期,请重新登陆!")));
return;
}
String username = claims.getSubject();
//获取用户信息
UserAuth userAuth = userAuthMapper.selectByUserName(username);
if (userAuth == null) {
throw new ServerException("用户不存在!");
}
UserInfo userInfo = userInfoMapper.selectById(userAuth.getUserInfoId());
List<String> roles = roleMapper.listRolesByUserInfoId(userInfo.getId());
/**
* ----------------------用户的文章点赞和留言点赞集合------------------------
*/
Set<Integer> articleLikeSet = (Set<Integer>) redisTemplate.boundHashOps(RedisPreFixConst.ARTICLE_USER_LIKE).get(userInfo.getId().toString());
Set<Integer> commentLikeSet = (Set<Integer>) redisTemplate.boundHashOps(RedisPreFixConst.COMMENT_USER_LIKE).get(userInfo.getId().toString());
UserInfoDTO userDetails = UserUtils.setUserDetails(userAuth, userInfo, roles, articleLikeSet, commentLikeSet, request);
//绑定用户和用户角色信息
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
chain.doFilter(request,response);
}
(6)添加过滤器
@Bean
public JWTFilter jwtFilter() throws Exception {
return new JWTFilter(authenticationManager());
}
.addFilter(jwtFilter())
(7)登出时,返回登出响应码,让前端删除token