Spring Boot 使用 拦截器 实现 token 验证
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();
}
}
Spring Boot 使用 拦截器 实现 token 验证的更多相关文章
- Spring Boot配置拦截器及实现跨域访问
拦截器功能强大,能够深入方法前后,常应用于日志记录.权限检查和性能检测等,几乎是项目中不可或缺的一部分,本文就来实现Spring Boot自定义拦截器的配置. 理论指导 问:Spring Boot怎么 ...
- spring boot 使用拦截器,注解 实现 权限过滤
http://www.cnblogs.com/zhangXingSheng/p/7744997.html spring boot 使用拦截器 实现 用户登录拦截 http://www.cnblogs. ...
- Spring Boot整合拦截器
过滤器和监听器都属于Servlet 的api,还可以使用 Spring 提供的拦截器(HandlerInterceptor)进行改更精细的控制.
- Spring Boot之拦截器与过滤器(完整版)
作者:liuxiaopeng 链接:http://www.cnblogs.com/paddix 作者:蓝精灵lx原文:https://blog.csdn.net/liuxiao723846/artic ...
- Spring Boot 配置拦截器方式
其实spring boot拦截器的配置方式和springMVC差不多,只有一些小的改变需要注意下就ok了.下面主要介绍两种常用的拦截器: 一.基于URL实现的拦截器: public class Log ...
- spring boot 添加拦截器
构建一个spring boot项目. 添加拦截器需要添加一个configuration @Configuration @ComponentScan(basePackageClasses = Appli ...
- spring boot 添加拦截器的简单实例(springBoot 2.x版本,添加拦截器,静态资源不可访问解决方法)
spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor 一.HandlerInterceptor HandlerInterceptor是s ...
- 【第四十章】Spring Boot 自定义拦截器
1.首先编写拦截器代码 package com.sarnath.interceptor; import javax.servlet.http.HttpServletRequest; import ja ...
- spring boot的拦截器简单使用
1.spring boot拦截器默认有: HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationIntercept ...
- Spring Boot (20) 拦截器
动态资源和静态资源 拦截器可以算是aop的一种实现,专门拦截对动态资源的后台请求,也就是拦截对控制层的请求,主要用于判断用户是否有权限请求后台.拦截器不会拦截静态资源,如spring boot默认静态 ...
随机推荐
- Serverless 工程实践 | Serverless 应用开发观念的转变
简介: Serverless 架构带来的除了一种新的架构.一种新的编程范式,还包括思路上的转变,尤其是开发过程中的一些思路转变.有人说要把 Serverless 架构看成一种天然的分布式架构,需要用 ...
- [FAQ] Argument 3 passed to Lcobucci\JWT\Signer\Hmac::doVerify() must be an instance of Lcobucci\JWT\Signer\Key, null given
出现这个错误,说明没有找到 key,在使用 laravel-jwt 之前需要生成加密 key,使用: $ php artisan jwt:secret Link:https://www.cnblogs ...
- 2019-8-31-dotnet-动态代理魔法书
title author date CreateTime categories dotnet 动态代理魔法书 lindexi 2019-08-31 16:55:58 +0800 2019-06-02 ...
- 一文搞懂drag&drop浏览器拖放功能的实现
拖放功能,即将一个元素从一个区域,通过拖拽,放置到另一个区域.常见的应用是将文件或图片从一个区域,拖放到另一个区域.中文常常把这表述成拖拽,实际上拖拽的描述并不准确,应该叫拖放,因为drag事件和dr ...
- 大模型_2.2:Prompt示例
1.行业洞察分析 行业洞察分析的方法论:使用麦肯锡工作法可以快速了解一个行业. Step1:通过搜索分析几十个与该行业相关的关键词,覆盖该行业的上下游,以获取全面的信息. Step2:阅读一些行业最新 ...
- 跟羽夏学 Ghidra ——简述
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...
- 模型微调-书生浦语大模型实战营学习笔记4&大语言模型7
大语言模型-7.模型微调 书生浦语大模型实战营学习笔记-4.模型微调 本节对应的视频教程为B站链接.笔记对视频的理论部分进行了整理.部分内容参考李宏毅2024春<生成式人工智能导论>和三分 ...
- JS实现下拉框切换和tab标签切换
现在商城网页上会有下拉框切换内容,是如何实现的呢,研究了一天,在调整js代码和查找bug.最终完成了自己想要的效果,我没有写CSS样式,只是实现了基本功能,如果对你有所帮助,可以自己写css,使其更加 ...
- 谈谈 Spring 的过滤器和拦截器
前言 我们在进行 Web 应用开发时,时常需要对请求进行拦截或处理,故 Spring 为我们提供了过滤器和拦截器来应对这种情况.那么两者之间有什么不同呢?本文将详细讲解两者的区别和对应的使用场景. ( ...
- 基于Vue3水印组件封装:防篡改守护!
基于Vue 3的全新水印通用组件.这款组件不仅功能强大,而且易于集成,能够轻松为您的网页或应用添加自定义水印,有效防止内容被篡改或盗用. 在线查看效果: 原文可查看效果地址 一,编写watermark ...