客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage
以后客户端每次与服务器通信,都要带上这个 JWT。
方式1、可以放在 Cookie 里面自动发送,但是这样不能跨域
方式2、更好的做法是放在 HTTP 请求的头信息Authorization字段里面
Authorization: Bearer
方式3、JWT放在POST请求的数据体body里面
这里使用springboot搭建工程,实现可以查询用户信息,不再赘述。
工程搭建详见: springboot的持久化的crud操作(注解版)_健康平安的活着的博客-CSDN博客
结构如下:
2.2 jwt的token获取,存储在进行认证通过后,创建令牌获取token,返回给前端,核心代码:
代码:
@GetMapping("/user/login") public Maplogin(User user) { log.info("用户名:{}", user.getName()); log.info("password: {}", user.getPassword()); Map map = new HashMap<>(); try { User userDB = userService.login(user); Map payload = new HashMap<>(); payload.put("id", userDB.getId()); payload.put("name", userDB.getName()); String token = JwtUtil.getToken(payload); map.put("state", true); map.put("msg", "登录成功"); map.put("token", token); return map; } catch (Exception e) { e.printStackTrace(); map.put("state", false); map.put("msg", e.getMessage()); map.put("token", ""); } return map; }
3.验证
2.3 jwt的token的验证假设要访问 :http://localhost:8981/user/verify 这个方法,但是需要进行token的验证合法性,这里需要添加一个拦截器,先进行过滤拦截,不合法则直接返回错误提示信息,如果合法则进行这个方法的执行,执行完成后返回给前端。
2.3.1.拦截器d代码package com.ljf.jwt.intercepter; import com.auth0.jwt.exceptions.AlgorithmMismatchException; import com.auth0.jwt.exceptions.InvalidClaimException; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ljf.jwt.util.JwtUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @Slf4j public class JWTInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取请求头中的令牌 String token = request.getHeader("Authorization"); log.info("当前token为:{}", token); Map2.3.2.注册启用拦截器map = new HashMap<>(); try { JwtUtil.verify(token); return true; } catch (SignatureVerificationException e) { e.printStackTrace(); map.put("msg", "签名不一致"); } catch (TokenExpiredException e) { e.printStackTrace(); map.put("msg", "令牌过期"); } catch (AlgorithmMismatchException e) { e.printStackTrace(); map.put("msg", "算法不匹配"); } catch (InvalidClaimException e) { e.printStackTrace(); map.put("msg", "失效的payload"); } catch (Exception e) { e.printStackTrace(); map.put("msg", "token无效"); } map.put("state", false); //响应到前台: 将map转为json String json = new ObjectMapper().writeValueAsString(map); response.setContentType("application/json;charset=UTF-8"); response.getWriter().println(json); return false; } }
package com.ljf.jwt.config; import com.ljf.jwt.intercepter.JWTInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JWTInterceptor()) .addPathPatterns("/user/verify") //加过滤验证,走拦截过滤,验证通过再走此请求的目标路径 .excludePathPatterns("/user/login") //此请求不走拦截器请求过滤,直接到达目标访问的资源 ; } }2.3.3 访问验证
1.过期的情况
2. 篡改token
这里故意将token开头字母ey......;改为3y......; 再次请求,提示token无效
3.正确的token
5.springboot整合JWT使用(一)_哔哩哔哩_bilibili
JWT〖一〗token单点登录认证逻辑实现_ktoking的博客-CSDN博客_jwt认证实现单点登录原理
代码地址:https://gitee.com/jurf-liu/jwt-demo.git