美文网首页
SpringBoot自定义注解实现Token校验(转载)

SpringBoot自定义注解实现Token校验(转载)

作者: lfboo | 来源:发表于2022-02-20 20:50 被阅读0次

    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);
        }
    }
    

    6.测试类

    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";
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot自定义注解实现Token校验(转载)

          本文链接:https://www.haomeiwen.com/subject/iznilrtx.html