SpringBoot自定义注解实现Token校验的方法

 更新时间:2021年03月15日 14:19:02   作者:李秀才  
这篇文章主要介绍了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校验就大功告成了。

到此这篇关于SpringBoot自定义注解实现Token校验的方法的文章就介绍到这了,更多相关SpringBoot Token校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于spring中单例Bean引用原型Bean产生的问题及解决

    关于spring中单例Bean引用原型Bean产生的问题及解决

    这篇文章主要介绍了关于spring中单例Bean引用原型Bean产生的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 浅谈JDK9的特性之JVM的xlog

    浅谈JDK9的特性之JVM的xlog

    在java程序中,我们通过日志来定位和发现项目中可能出现的问题。在现代java项目中,我们使用log4j或者slf4j,Logback等日志记录框架来处理日志问题。本文将介绍JDK9的特性之JVM的xlog。
    2021-06-06
  • Java算法练习题,每天进步一点点(2)

    Java算法练习题,每天进步一点点(2)

    方法下面小编就为大家带来一篇Java算法的一道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • SpringCloud hystrix服务降级学习笔记

    SpringCloud hystrix服务降级学习笔记

    什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作
    2022-10-10
  • 使用Spring Boot上传文件功能

    使用Spring Boot上传文件功能

    上传文件是互联网中常应用的场景之一,最典型的情况就是上传头像等,今天就带着大家做一个Spring Boot上传文件的小案例,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-01-01
  • Java实现队列的三种方法集合

    Java实现队列的三种方法集合

    这篇文章主要介绍了Java实现队列的三种方法集合,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • java利用oss实现下载功能

    java利用oss实现下载功能

    这篇文章主要为大家详细介绍了java利用oss实现下载功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • springboot vue项目管理前后端实现编辑功能

    springboot vue项目管理前后端实现编辑功能

    这篇文章主要为大家介绍了springboot vue项目管理前后端实现编辑功能,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 聊聊ResourceBundle和properties读取配置文件的区别

    聊聊ResourceBundle和properties读取配置文件的区别

    这篇文章主要介绍了ResourceBundle和properties读取配置文件的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • svn 清理失败 (cleanup 失败) 的快速解决方法

    svn 清理失败 (cleanup 失败) 的快速解决方法

    下面小编就为大家带来一篇svn 清理失败 (cleanup 失败) 的快速解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10

最新评论