SpringBoot自定义注解实现Token校验的方法
作者:李秀才 发布时间:2023-11-13 23:17:52
标签:SpringBoot,Token,校验
1.定义Token的注解,需要Token校验的接口,方法上加上此注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Token {
boolean validate() default true;
}
2.定义LoginUser注解,此注解加在参数上,用在需要从token里获取的用户信息的地方
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
3.权限的校验 *
import com.example.demo.annotation.Token;
import com.example.demo.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Slf4j
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
public static final String USER_KEY = "USER_ID";
public static final String USER_INFO = "USER_INFO";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Token annotation;
if(handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(Token.class);
}else{
return true;
}
//没有声明需要权限,或者声明不验证权限
if(annotation == null || annotation.validate() == false){
return true;
}
//从header中获取token
String token = request.getHeader("token");
if(token == null){
log.info("缺少token,拒绝访问");
return false;
}
//查询token信息
// User user = redisUtils.get(USER_INFO+token,User.class);
// if(user == null){
// log.info("token不正确,拒绝访问");
// return false;
// }
//token校验通过,将用户信息放在request中,供需要用user信息的接口里从token取数据
request.setAttribute(USER_KEY, "123456");
User user=new User();
user.setId(10000L);
user.setUserName("2118724165@qq.com");
user.setPhoneNumber("15702911111");
user.setToken(token);
request.setAttribute(USER_INFO, user);
return true;
}
}
4.写参数的解析器,将登陆用户对象注入到接口里
import com.example.demo.annotation.LoginUser;
import com.example.demo.entity.User;
import com.example.demo.interceptor.AuthorizationInterceptor;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver
{
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().isAssignableFrom(User.class)&&methodParameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
//获取登陆用户信息
Object object = nativeWebRequest.getAttribute(AuthorizationInterceptor.USER_INFO, RequestAttributes.SCOPE_REQUEST);
if(object == null){
return null;
}
return (User)object;
}
}
5.配置 * 和参数解析器
import com.example.demo.interceptor.AuthorizationInterceptor;
import com.example.demo.resolver.LoginUserHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthorizationInterceptor authorizationInterceptor;
@Autowired
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/api/**");
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
}
}
7.测试类
import com.example.demo.annotation.LoginUser;
import com.example.demo.annotation.Token;
import com.example.demo.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api")
@Slf4j
public class TestController {
@RequestMapping(value="/test",method = RequestMethod.POST)
@Token
public String test(@LoginUser User user){
System.out.println("需要token才可以访问,呵呵……");
log.info("user:"+user.toString());
return "test";
}
@RequestMapping(value="/noToken",method = RequestMethod.POST)
public String noToken(){
System.out.println("不用token就可以访问……");
return "test";
}
}
至此,自定义注解实现token校验就大功告成了。
来源:https://blog.csdn.net/qq_33556185/article/details/105420205
0
投稿
猜你喜欢
- 使用ProcessBuilder踩到的坑最近使用ProcessBuilder执行命令,命令内容正确,但始终报错命令实行失败,是因为不熟悉Pr
- 前言:封装、继承和多态是面向对象编程的三大特征。1.封装1.1.封装概念封装就是把抽象出的数据(属性)和对数据的操作(方法)封装在一起,数据
- GitHub有一个开源控件PickerView,可以实现 * 联动的效果。虽然该控件使用非常简单,但是填充数据异常繁琐。GitHub上的Dem
- 核心思想:“分”与“合”。主体流程先将一个序列分成很多个不能再分割的子序列,将各个子序列分别排序后再将子序列合并。其实就是重复两个步骤:【1
- 一、Stream流简单示例需求:按照要求集合创建和遍历创建一个结合,存储多个字符串元素把集合中所有以"张"开头的元素存储
- Android SDK已经提供有进度条组件ProgressDialog组件,但用的时候我们会发现可能风格与我们应用的整体风格不太搭配,而且P
- 本文实例为大家分享了Unity排行榜优化滚动效果的具体代码,供大家参考,具体内容如下自己做的一个优化排行榜的功能,当有大量的数据需要在scr
- 有时候你可能需要通过代码来控制执行linux命令实现某些功能。针对这类问题可以使用JSCH来实现,具体代码如下:public class C
- 1.使用usb口输入的扫描枪,这里实现使用了winform首先创建一个CS文件using System;using System.Colle
- 本文基于Java实现了一个简单的单词本安卓a
- Java中线程分为两种类型:用户线程和守护(服务)线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.
- 本文实例为大家分享了Android仿iPhone时间选择器的具体代码,供大家参考,具体内容如下先看效果图如何使用import java.te
- 最近学习Spring,一直不太明白Srping的切面编程中的的argNames的含义,经过学习研究后,终于明白,分享一下需要监控的类:pac
- 对 Excel 进行读写操作是生产环境下常见的业务,网上搜索的实现方式都是基于POI和JXL第三方框架,但都不是很全面。小编由于这两天刚好需
- 1.进入<Android_Source_Path>/build/target/product/security,找到【platf
- 一、前期准备提示:如果友友你没有看过系列一的文章点击这个链接:王者荣耀中一个英雄是怎么被产生的?(一)我们现在功能比较多,所有为了让程序运行
- 先看看常规的隐藏状态栏的方法:方法一:@Overrideprotected void onCreate(Bundle savedInstan
- 本文实例为大家分享了Android实现类似微信视频接听的具体代码,供大家参考,具体内容如下1、背景需求:业务需要接入视频审核功能,在PC 端
- 前言这篇文章探索一下springboot的tomcat是如何实现的一、起步依赖1.首先我们了解一下起步依赖SpringBoot结合Maven
- 微信公众号发送模版消息 背景:如下图,当用户发布需求的时候,公众号自定推送消息。例如:微信支付的时候,公众号会推送支付成功消息前提:发送模版