这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
JWT整合spingboot+redis
controller
将生成token写入登录的controller中并且存入redis
@ResponseBody
@PostMapping("/login")
/*认证生成token*/
public HashMap< String, Object > login(String username,String password){
HashMap< String, String > map = new HashMap<>();
HashMap< String, Object > map1 = new HashMap<>();
try {
User user = loginSercice.loginSuccess(username, password);
if (user != null) {
//将用户名和密码存放map,用于生成搭载信息的token,注意,不要放密码进去!
map.put("id", user.getId());
map.put("username", user.getUsername());
String token = JWTUtil.create(map);
map1.put("status",200);
map1.put("token",token);
return map1;
}
}catch (Exception e){
map1.put("status",500);
}
return map1;
}
拦截器
将验证token写进handler拦截器中,除了登录功能,其他功能都会被拦截检查token
token 存放在request的请求头中,所以可以通过request.getHeader("token")来获取token
/*这部分相当于验证token的功能*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HashMap< String, Object > map = new HashMap<>();
//获得token
String token = request.getHeader("token");
try{
JWTUtil.verify(token); //验证令牌
//当数据库中的token没有过期且与前端传来的token相同
if(StringUtils.equals(redisUtil.get("token"),token)){
map.put("message","不拦截");
return true;
}else {
map.put("error","登录超时,请重新登录");
}
}catch (Exception e){
e.printStackTrace();
map.put("message","没有登录,请重新登录");
}
map.put("status",false);
//将map转换为json
String json = new ObjectMapper().writeValueAsString(map);
//设置response的格式为json 比那与前后端
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
拦截器部署
别忘了将拦截器应用到webMVC中
并将除了登录生成token的其他所有的访问路径纳入拦截器的范围
那么每次访问请求路径都会经过拦截器来校验。
当登录后,在拦截器中读取redis的值与token进行对比时,出现redis读取的值为null。
查找得知,拦截器在springcontext之前就加载了,即实例化在@Bean之前执行,那么当拦截器运行,redisTemplate实际上是注入失败的(无法进行读取操作)
所以我们要先实例化拦截器,再将拦截器配置进去
@Bean
public JWTHandler getHandler(){
return new JWTHandler();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//调用实例化的方法
registry.addInterceptor(getHandler())
.addPathPatterns("/login/**")
.excludePathPatterns("/login/login");
}