后端Jwt实现Token编码、解码以及axios的request哀求头的Token传输方式 ...

打印 上一主题 下一主题

主题 1021|帖子 1021|积分 3063

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目次
一、什么是JWT:
二、Jwt的利用:
第一步:引入依靠:
第二步:设置拦截器:JwtInterceptor.java:
其中非常文件ServiceException设置如下:
全局非常文件GlobalException.java文件设置如下:
其中所需的Result设置如下:
第三步:设置拦截设置文件:InterceptorConfig.java:
第四步:设置Token工具类文件:TokenUtils.java:
request.js的axios封装文件为:
文件结构大致如下:


一、什么是JWT:

        JWT是token的一种实现方式,全称是:JSON Wwb Token。简单来讲,Jwt是一种字符串,可以根据用户信息进行相干的编码操纵生成带有效户信息的JWT token,我们可以根据这个来判断其信息是否准确或者是否被篡改。
二、Jwt的利用:

  1. 首先是后端:
复制代码
第一步:引入依靠:

  1.                 <dependency>
  2.                         <groupId>com.auth0</groupId>
  3.                         <artifactId>java-jwt</artifactId>
  4.                         <version>4.3.0</version>
  5.                 </dependency>
复制代码
第二步:设置拦截器:JwtInterceptor.java:

  1. import com.auth0.jwt.JWT;
  2. import com.auth0.jwt.JWTVerifier;
  3. import com.auth0.jwt.algorithms.Algorithm;
  4. import com.auth0.jwt.exceptions.JWTVerificationException;
  5. import com.example.cqcrhouduan.Utils.TokenUtils;
  6. import com.example.cqcrhouduan.exception.ServiceException;
  7. import com.example.cqcrhouduan.mapper.UserMapper;
  8. import io.micrometer.common.util.StringUtils;
  9. import jakarta.servlet.http.HttpServletRequest;
  10. import jakarta.servlet.http.HttpServletResponse;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.stereotype.Component;
  14. import org.springframework.web.servlet.HandlerInterceptor;
  15. @Component
  16. @Slf4j
  17. public class JwtInterceptor implements HandlerInterceptor {
  18.     @Autowired
  19.     private UserMapper userMapper;
  20.     @Override
  21.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
  22.         if(request.getMethod().equals("OPTIONS"))
  23.         {
  24.             return true;
  25.         }
  26.         String token = request.getHeader("token");
  27.         if (StringUtils.isEmpty(token)) {
  28.             token = request.getParameter("token");
  29.         }
  30.         token = token;
  31.         // 执行认证
  32.         if (StringUtils.isEmpty(token)) {
  33.             throw new ServiceException(401, "无token,请重新登录");
  34.         }
  35.         // 获取 token 中的adminId
  36.         String userId;
  37.         User user;
  38.         try {
  39.             userId = JWT.decode(token).getAudience().get(0);  //解码
  40.         // 根据token中的userid查询数据库
  41.             user = userMapper.getById(Integer.parseInt(userId));
  42.             user = user;
  43.         } catch (Exception e) {
  44.             String errMsg = "token验证失败,请重新登录";
  45.             log.error(errMsg + ", token=" + token, e);
  46.             throw new ServiceException(401, errMsg);
  47.         }
  48.         if (user == null) {
  49.             throw new ServiceException(401, "用户不存在,请重新登录");
  50.         }
  51.         try {
  52.             // 用户密码加签验证 token
  53.             JWTVerifier jwtVerifier =            
  54.             JWT.require(Algorithm.HMAC256(user.getPassword())).build();
  55.             jwtVerifier.verify(token); // 验证token
  56.         } catch (JWTVerificationException e) {
  57.             throw new ServiceException(401, "token验证失败,请重新登录");
  58.         }
  59.         return true;
  60.     }
  61. }
复制代码
其中非常文件ServiceException设置如下:

  1. import com.example.cqcrhouduan.pojo.Result;
  2. import lombok.Data;
  3. @Data
  4. public class ServiceException extends RuntimeException {
  5.     private int code;
  6.     public ServiceException(String msg){
  7.         super(msg);
  8.         this.code = 500;
  9.     }
  10.     public ServiceException(int code, String msg){
  11.         super(msg);
  12.         this.code = code;
  13.     }
  14. }
复制代码
全局非常文件GlobalException.java文件设置如下:

  1. import com.example.cqcrhouduan.pojo.Result;
  2. import org.springframework.web.bind.annotation.ControllerAdvice;
  3. import org.springframework.web.bind.annotation.ExceptionHandler;
  4. import org.springframework.web.bind.annotation.ResponseBody;
  5. //自定义异常
  6. @ControllerAdvice
  7. public class GlobalException {
  8.     @ExceptionHandler(ServiceException.class)
  9.     @ResponseBody
  10.     public Result serviceException(ServiceException e){
  11.         return Result.error(e.getCode(),e.getMessage());
  12.     }
  13. }
复制代码
其中所需的Result设置如下:

  1. import lombok.AllArgsConstructor;
  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;
  4. @Data
  5. @NoArgsConstructor
  6. @AllArgsConstructor
  7. public class Result {
  8.     private Integer code;
  9.     private String msg;
  10.     private Object data;
  11.     public static Result success(Object data){
  12.         return new Result(200,"success",data);
  13.     }
  14.     public static Result success(){
  15.         return new Result(200,"success",null);
  16.     }
  17.     public static Result error(String msg){
  18.         return new Result(500,msg,null);
  19.     }
  20.     public static Result error(Integer Code ,String msg){
  21.         return new Result(Code,msg,null);
  22.     }
  23. }
复制代码
第三步:设置拦截设置文件:InterceptorConfig.java:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
  5. @Configuration
  6. public class InterceptorConfig extends WebMvcConfigurationSupport {
  7.     // 加自定义拦截器JwtInterceptor,设置拦截规则
  8.     @Override
  9.     protected void addInterceptors(InterceptorRegistry registry) {
  10.         registry.addInterceptor(jwtInterceptor())
  11.                 .addPathPatterns("/**")
  12.                 .excludePathPatterns("/login","/register");
  13.         super.addInterceptors(registry);
  14.     }
  15.     @Bean
  16.     public JwtInterceptor jwtInterceptor(){
  17.         return new JwtInterceptor();
  18.     }
  19. }
复制代码
第四步:设置Token工具类文件:TokenUtils.java:

  1. import com.auth0.jwt.JWT;
  2. import com.auth0.jwt.algorithms.Algorithm;
  3. import com.example.cqcrhouduan.mapper.UserMapper;
  4. import com.example.cqcrhouduan.pojo.User;
  5. import jakarta.annotation.PostConstruct;
  6. import jakarta.annotation.Resource;
  7. import jakarta.servlet.http.HttpServletRequest;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.context.request.RequestContextHolder;
  12. import org.springframework.web.context.request.ServletRequestAttributes;
  13. @Component
  14. @Slf4j
  15. public class TokenUtils {
  16.     private static UserMapper staticAdminService;
  17.     @Resource
  18.     private UserMapper adminService;
  19.     @PostConstruct
  20.     public void setUserService() {
  21.         staticAdminService = adminService;
  22.     }
  23.     /**
  24.      * 生成token
  25.      *
  26.      * @return
  27.      */
  28.     public static String genToken(int adminId, String sign) {
  29.         return JWT.create().withAudience(Integer.toString(adminId)) // 将 user id 保存到 token 里面,作为载荷
  30.                 .withExpiresAt(DateUtil.offsetHours(new Date(), 2)) // 2小时后token过期
  31.                 .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
  32.     }
  33.     /**
  34.      * 获取当前登录的用户信息
  35.      *
  36.      * @return user对象
  37.      *  /admin?token=xxxx
  38.      */
  39.     public static User getCurrentAdmin() {
  40.         String token = null;
  41.         try {
  42.             HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  43.             token = request.getHeader("token");
  44.             if (StringUtils.isNotBlank(token)) {
  45.                 token = request.getParameter("token");
  46.             }
  47.             if (StringUtils.isBlank(token)) {
  48.                 log.error("获取当前登录的token失败, token: {}", token);
  49.                 return null;
  50.             }
  51.             String userId = JWT.decode(token).getAudience().get(0);
  52.             return staticAdminService.getById(Integer.valueOf(userId));
  53.         } catch (Exception e) {
  54.             log.error("获取当前登录的管理员信息失败, token={}", token,  e);
  55.             return null;
  56.         }
  57.     }
  58. }
复制代码
  1. 然后是前端axios配置:
复制代码
request.js的axios封装文件为:

  1. import axios from "axios";
  2. import router from "../modules/router.js";
  3. const request = axios.create({
  4.     baseURL:'http://localhost:8080/',  //自己的请求地址
  5.     timeout:30000,
  6. })
  7. // Add a request interceptor
  8. request.interceptors.request.use((config) => {
  9.     config.headers['Content-Type'] = 'application/json;charset=utf-8';
  10.     let user = JSON.parse(localStorage.getItem("userToken") || '{}')
  11.     // console.log(user.token)  //查看token
  12.     config.headers['token'] = user.token
  13.     // config.headers.Authorization = localStorage.getItem("userToken")
  14.     console.log("ok")
  15.     // Do something before request is sent
  16.     return config;
  17. }, error => {
  18.     console.log('request error' + error)
  19.     // Do something with request error
  20.     return Promise.reject(error);
  21. });
  22. // Add a response interceptor
  23. request.interceptors.response.use(response => {
  24.     let res = response.data;
  25.     if (typeof res === 'string'){
  26.         res = res ? JSON.parse(res) : res
  27.     }
  28.     // if(res.code === 401){ //自动跳转
  29.     //     router.push('/')
  30.     // }
  31.     // Any status code that lie within the range of 2xx cause this function to trigger
  32.     // Do something with response data
  33.     return res;
  34. }, function (error) {
  35.     // Any status codes that falls outside the range of 2xx cause this function to trigger
  36.     // Do something with response error
  37.     console.log('response error' + error)
  38.     return Promise.reject(error);
  39. });
  40. export default request
复制代码
文件结构大致如下:



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

伤心客

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表