• SpringBoot自定义注解实现Token校验


    原文链接: https://blog.csdn.net/qq_33556185/article/details/105420205

    https://blog.csdn.net/weixin_43877725/article/details/107554638

    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.HandlerInterceptor;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    @Component
    @Slf4j
    public class AuthorizationInterceptor implements HandlerInterceptor {
    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_INFO, user);
    return true;
    }

    //自定义验证失败返回的参数
    private static void printJson(HttpServletResponse response) {

    String content = JSON.toJSONString(,"token验证失败");
    printContent(response, content);

    }

    //在DispatcherServlet完全处理完请求后被调用,可用于清理资源,返回处理等
    private static void printContent(HttpServletResponse response, String content) {
    try {
    response.reset();
    response.setContentType("application/json");
    response.setHeader("Cache-Control", "no-store");
    response.setCharacterEncoding("UTF-8");
    PrintWriter pw = response.getWriter();
    pw.write(content);
    pw.flush();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }


    }
    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校验就大功告成了。

  • 相关阅读:
    truncate、delete和drop的异同点
    改机器名处理
    全文目录
    利用TypePerf.exe
    wait_stats状态初始化
    Android模拟器 SD卡的权限详解
    Android Animation学习笔记
    Android学习笔记
    Android Activity和Intent机制学习笔记
    Android学习笔记33:Intent介绍及Intent在Activity中的使用方法
  • 原文地址:https://www.cnblogs.com/fswhq/p/16365761.html
Copyright © 2020-2023  润新知