关于注解拦截器的问题

springboot项目里想加个token拦截,用的是注解拦截的方法,目前的问题是在
在controller方法接口头上添加了这个注解,也就是说没有登录不能访问这个接口。但实际效果是可以访问。求点拨。

    @UserLoginToken(required = false)

注解如下

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/*RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,
所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}



这是处理工具类


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.vue02demo.annotation.PassToken;
import com.example.vue02demo.annotation.UserLoginToken;
import com.example.vue02demo.entity.User;
import com.example.vue02demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    UserService userService;

    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new RuntimeException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用户不存在,请重新登录");
                }
                // 验证 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}





把你controller层代码放出来呀。提问题要全面点。
还有你是先判断@PassToken 注解的,如果controller加入了这个注解,就算你加上@UserLoginToken 也会访问到。
我这边是这么写的:

img

img

使用拦截器时,你要注意,拦截器是有配置那些接口需要拦截,哪些接口不需要拦截,如果你当前访问的接口是放开的,那访问时,是不会走拦截器的逻辑的,具体配置拦截的类需要实现接口WebMvcConfigurer,如果没有实现这个类,那么springmvc会采用默认的拦截器进行拦截,也就是默认放开

引用GPT作答
@UserLoginToken(required = false) 是一个注解,通常用于标记需要用户登录才能访问的接口或方法。在这个例子中,required = false 表示该接口或方法可以选择是否需要用户登录。如果设置为 true,则表示该接口或方法需要用户登录才能访问;如果设置为 false,则表示该接口或方法可以在用户未登录的情况下访问。

这个注解通常与身份验证和授权功能一起使用,以确保只有经过身份验证和授权的用户才能访问特定的接或方法。

required = false 改成 required = true 之后,重新编译运行试试, 由于设置为了 非必须传递的参数~,望采纳

【相关推荐】




如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

第一:@UserLoginToken(required = false),第二:preHandle前面是不是少@Override,总感觉你是没有进入拦截器里面,不行你就跟代码吧

拦截器配置了吗?