使用JWT验证登陆(拦截器实现)

今天药忘吃喽~ 2023-10-12 14:29 104阅读 0赞

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:

  • Header
  • Payload
  • Signature

因此,一个典型的JWT看起来是这个样子的:

xxxxx.yyyyy.zzzzz

详细了解可查看: 知乎:5分钟带你了解JWT

1.引入jwt的jar包。

  1. <!--引入JWT-->
  2. <dependency>
  3. <groupId>com.auth0</groupId>
  4. <artifactId>java-jwt</artifactId>
  5. <version>3.10.0</version>
  6. </dependency>

2.编写token工具类,其中包含生成token方法 和 验证token方法。

  1. package cn.pjh.everyDay.utils;
  2. import com.auth0.jwt.JWT;
  3. import com.auth0.jwt.JWTCreator;
  4. import com.auth0.jwt.algorithms.Algorithm;
  5. import com.auth0.jwt.interfaces.DecodedJWT;
  6. import java.util.Calendar;
  7. import java.util.Map;
  8. public class JWTUtils {
  9. //加密盐 使用它来加密解密
  10. private static final String sign = "9jIWOD9idje91@#*9wofj+%5895d123";
  11. /**
  12. * 生成token header.payload.sign
  13. */
  14. public static String getToken(Map<String,String> map){
  15. //生成过期时间
  16. Calendar instance = Calendar.getInstance();
  17. instance.add(Calendar.SECOND,20);
  18. JWTCreator.Builder builder = JWT.create();
  19. //将传入进来的参数存入token,比如用户id
  20. map.forEach((k,v)->{
  21. builder.withClaim(k,v);
  22. });
  23. //生成token使用HMAC256算法
  24. String token = builder.withExpiresAt(instance.getTime())
  25. .sign(Algorithm.HMAC256(sign));
  26. return token;
  27. }
  28. /**
  29. * 获取token信息方法
  30. */
  31. public static DecodedJWT getTokenInfo(String token){
  32. //解析token拿出内容,加密的时候使用的什么算法这里就要用什么算法解析(HMAC256)
  33. DecodedJWT verify = JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
  34. return verify;
  35. }
  36. }

3.编写拦截器类

  1. package cn.pjh.everyDay.interceptors;
  2. import cn.pjh.everyDay.common.R;
  3. import cn.pjh.everyDay.utils.JWTUtils;
  4. import com.alibaba.fastjson.JSON;
  5. import com.auth0.jwt.exceptions.AlgorithmMismatchException;
  6. import com.auth0.jwt.exceptions.SignatureVerificationException;
  7. import com.auth0.jwt.exceptions.TokenExpiredException;
  8. import org.springframework.web.servlet.HandlerInterceptor;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. public class JWTInterceptor implements HandlerInterceptor {
  12. @Override
  13. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  14. //从请求头中获取token
  15. String token = request.getHeader("token");
  16. //如果验证未成功直接拦截,并返回原因
  17. R r = new R<>();
  18. try {
  19. //验证token
  20. JWTUtils.getTokenInfo(token);
  21. //验证成功没有异常直接放行
  22. return true;
  23. }catch (SignatureVerificationException e){
  24. e.printStackTrace();
  25. //签名不对抛出的异常
  26. r.setCode(0);
  27. r.setMsg("无效签名");
  28. }catch (TokenExpiredException e){
  29. //token过期抛出的异常
  30. e.printStackTrace();
  31. r.setCode(0);
  32. r.setMsg("登陆验证过期");
  33. }catch (AlgorithmMismatchException e){
  34. //算法不一致发生的异常
  35. e.printStackTrace();
  36. r.setCode(0);
  37. r.setMsg("登陆异常");
  38. }
  39. //转存json字符串通过response打印流返回给客户端
  40. String r1 = JSON.toJSONString(r);
  41. response.setContentType("application/json;charset=UTF-8");
  42. response.getWriter().println(r1);
  43. return false;
  44. }
  45. }

4.将拦截器注册到mvc

  1. package cn.pjh.everyDay.config;
  2. import cn.pjh.everyDay.interceptors.JWTInterceptor;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. @Configuration
  7. public class InterceptorConfig implements WebMvcConfigurer {
  8. @Override
  9. public void addInterceptors(InterceptorRegistry registry) {
  10. //mvc配置类中添加拦截器
  11. registry.addInterceptor(new JWTInterceptor())//需要添加的拦截器类
  12. .addPathPatterns("/**")//需要拦截的路径
  13. .excludePathPatterns("user/login");//需要排除的路径
  14. }
  15. }

5.编写登陆接口()

  1. @PostMapping("/login")
  2. public R<Map> loginUser(User user) {
  3. //数据库查找到当前用户
  4. User u = userService.getById(user);
  5. //如果查询到数据就登陆成功否则失败
  6. if (u != null){
  7. //将需要token存储的信息放入map集合
  8. Map<String, String> map = new HashMap<>();
  9. map.put("id", u.getId().toString());
  10. //通过工具类生成token
  11. String token = JWTUtils.getToken(map);
  12. //返回一个当前用户的信息和token的map集合,然后交给前端人员,设置访问时将token设置到请求头里面
  13. Map<String, Object> r = new HashMap<>();
  14. r.put("userId", u.getId());
  15. r.put("username", u.getName());
  16. r.put("phone", u.getPhone());
  17. r.put("token", token);
  18. return R.success(r);
  19. }
  20. return R.error("请检查账号或密码");
  21. }

登陆成功之后前端将返回数据里面的token保存在localStorage或者sessionStorage中,之后每次访问将token设置到请求头里面进行访问。

退出账号则前端直接删除掉本地的token。

发表评论

表情:
评论列表 (有 0 条评论,104人围观)

还没有评论,来说两句吧...

相关阅读