首页 > 其他分享 >Spring Boot 使用 拦截器 实现 token 验证

Spring Boot 使用 拦截器 实现 token 验证

时间:2024-01-15 19:22:39浏览次数:39  
标签:ResponseData 拦截器 return String Spring Boot private token public

Spring Boot 使用 拦截器 实现 token 验证

整体思路:
1.写一个工具类封装生成、校验和解析 token 的方法;
2.在注册和登录时生成 token ,生成的 token 存入 redis ,下次登录去 redis 获取,如果存在则直接返回通过
3.在拦截器中校验和解析 token ,拿到 token 中有用的信息存入 private static final InheritableThreadLocal<UserDto> *THREAD_LOCAL* = new InheritableThreadLocal<>(); ,以便后续取用。

实现
1.过滤器
2.网关,spring zuul 经过网关:对登录的权限做限制。


1.JWT方案,可以将登录后的数据加密后通过请求头传输,在接收端接口中可以直接解析来使用。比如:用户ID,用户名称。更多的使用于不可变化的参数。
2.Authorization: 手机号+UUID方案,目前平台都是通过手机号作为账号,附加UUID,作为请求头发起请求,在接收端接口中,根据解析的手机号,通过redis中保存的手机号+UUID是否一致。
验证通过之后,可以通过该手机号查询该手机号的相关信息,比如权限,角色(动态变化的参数),然后保存到InheritableThreadLocal对象中。
String uuid = UUID.randomUUID().toString().replace("-", "");

例如:代码片段

public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取 header 中的 Authorization 信息
        String token = request.getHeader("Authorization"); 
    
         UserHolder.remove();
    //对token验证
    //验证不通过
        throw new BusinessException("0", "没有登录或登录失效,请重新登录");  //全局异常捕获
    //验证通过
    //封装用户信息
        UserHolder.setUserInfo(userLoginInfo);
    
    return true;    
}

//全局异常捕获
package com.example.core.mydemo.java;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@Slf4j
@ControllerAdvice
public class GlobalExceptionAdvisor {
    /**
     * 系统异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResponseData handleException(Exception e){
        log.error("GlobalExceptionAdvisor.handleException",e);
        ResponseData responseData = new ResponseData("code","msg");
        return responseData;
    }

    /**
     * 业务异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(BusinessException.class)
    public ResponseData handleBusinessException(BusinessException e){
        log.error("GlobalExceptionAdvisor.handleOrderException",e);
        ResponseData responseData = new ResponseData(e.getResCode(),e.getMessage());
        return responseData;
    }
}



public class ResponseData<T> {

    private static final long serialVersionUID = 6898451165550538312L;
    @AutoDocProperty(value = "返回代码")
    private String resCode;
    @AutoDocProperty(value = "返回消息")
    private String resMsg;
    @AutoDocProperty(value = "返回实体")
    private T data;

    public ResponseData() {
    }

    public ResponseData(String resCode, String resMsg) {
        this.resCode = resCode;
        this.resMsg = resMsg;
    }

    public String getResCode() {
        return resCode;
    }

    public void setResCode(String resCode) {
        this.resCode = resCode;
    }

    public String getResMsg() {
        return resMsg;
    }

    public void setResMsg(String resMsg) {
        this.resMsg = resMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

package com.example.core.mydemo.java;

public class UserLoginInfoVo {
    private String userId;
    private String userName;

    public UserLoginInfoVo() {
        super();
    }

    public UserLoginInfoVo(String userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}


package com.example.core.mydemo.java;

import java.util.ArrayList;
import java.util.List;

/**
 * 存放用户信息的容器
 */
public class UserHolder {
    private static final InheritableThreadLocal<UserLoginInfoVo> THREAD_LOCAL = new InheritableThreadLocal<UserLoginInfoVo>(){
        @Override
        protected UserLoginInfoVo initialValue() {
            //初始化对象
            UserLoginInfoVo userLoginInfoVo = new UserLoginInfoVo("1","admin");
            return userLoginInfoVo;
        }
    };

    private UserHolder() {
    }

    /**
     * 获取线程中的用户
     * @return 用户信息
     */
    public static UserLoginInfoVo getUserInfo() {
        return THREAD_LOCAL.get();
    }

    /**
     * 设置当前线程中的用户
     * @param info 用户信息
     */
    public static void setUserInfo(UserLoginInfoVo info) {
        THREAD_LOCAL.set(info);
    }

    /**
     * 获取登录的用户的ID
     * @return
     */
    public static String getUserId() {
        UserLoginInfoVo dto = THREAD_LOCAL.get();
        if (dto != null) {
            return dto.getUserId();
        } else {
            // 注册或登录时没有,返回 0
            return "";
        }
    }

    public static void remove() {
        THREAD_LOCAL.remove();
    }
}

 

标签:ResponseData,拦截器,return,String,Spring,Boot,private,token,public
From: https://www.cnblogs.com/oktokeep/p/17966114

相关文章

  • springboot项目配置多数据源
    springboot项目配置多数据源//关键:mybatis文件的目录需要区分开来sqlSessionFactoryBean.setMapperLocations(newPathMatchingResourcePatternResolver().getResources("classpath:mybatis.myProjectOne/*.xml"));#从数据库配置,数据库的配置以spring.datasource.myPr......
  • spring mvc GET请求方式及传参
    springmvcGET请求方式及传参@Api(tags="管理接口")@Slf4j@RestController@RequestMapping("/myOutApi/public/test")publicclassMyManageController{@AutowiredMyInfoServicemyInfoService;@ApiOperation(value="查询信息")......
  • Idea SpringBoot 子模块 加载不到该子模块根目录config下面的配置文件
    IdeaSpringBoot子模块加载不到该子模块根目录config下面的配置文件importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframew......
  • Spring学习记录之Spring6整合JUnit4-JUnit5
    Spring学习记录之Spring6整合JUnit4-JUnit5前言这篇文章是我第二次学习b站老杜的spring相关课程所进行的学习记录,算是对课程内容及笔记的二次整理,以自己的理解方式进行二次记录,其中理解可能存在错误,欢迎且接受各位大佬们的批评指正;关于本笔记,只是我对于相关知识遗忘时快速查阅......
  • Spring学习记录之Spring对事务的支持
    Spring学习记录之Spring对事务的支持前言这篇文章是我第二次学习b站老杜的spring相关课程所进行的学习记录,算是对课程内容及笔记的二次整理,以自己的理解方式进行二次记录,其中理解可能存在错误,欢迎且接受各位大佬们的批评指正;关于本笔记,只是我对于相关知识遗忘时快速查阅了解使......
  • springboot + mybatis plus 全局添加查询字段反引号
    配置文件添加: column-format:"`%s`"mybatis-plus:#启动时是否检查MyBatisXML文件是否存在check-config-location:true#MyBatis原生配置configuration:#字段名称下划线转驼峰命名map-underscore-to-camel-case:trueglobal-config:db-co......
  • Spring 中的设计模式详解
    1、控制反转(IoC)和依赖注入(DI)IoC是一个原则,而不是一个模式,以下模式(但不限于)实现了IoC原则。 控制反转怎么理解呢? 举个例子:"对象a依赖了对象b,当对象a需要使用对象b的时候必须自己去创建。但是当系统引入了IOC容器后,对象a和对象b之前就失去了直接的......
  • Spring 事务详解
    JavaGuide(gitee.io)1、Spring事务管理接口介绍Spring框架中,事务管理相关最重要的3个接口如下:**PlatformTransactionManager**:(平台)事务管理器,Spring事务策略的核心。**TransactionDefinition**:事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。**Trans......
  • uboot-5_bootm/bootz启动内核过程
    1images全局变量不管是bootz还是bootm命令,启动kernel都会用到images全局变量。images定义在文件cmd/bootm.c:include/image.h中的定义了bootm_headers_t结构:该结构描述的是bootm启动时的头部信息。该结构又包含了系统镜像头部和系统镜像。1.1bootm头部结构304type......
  • SpringBoot中整合ElasticSearch实现增删改查等操作
    场景SpringBoot中整合ElasticSearch快速入门以及踩坑记录:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135599698在上面进行集成的基础上,实现对ES数据的增删改查等操作。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现1、ElastciSearch的对象映射h......