SpringBoot如何优雅的处理免登录接口

在项目开发过程中,会有很多API接口不需要登录就能直接访问,比如公开数据查询之类的 ~

常规处理方法基本是 使用拦截器过滤器,拦截需要认证的请求路径。在拦截器中判断session或token信息,如果存在则放行,否则跳转到登录页。过滤器原理与拦截器类似,可以在过滤器中判断请求的session或token信息,麻烦的地方就是:每次开发新的免登录接口的时候,都需要去配置一下路径

今天介绍一个更优雅的方法:自定义注解的方式

基本思路是:自定义一个注解,在不需要校验登录的Controller方法或类上使用该注解。通过AOP或拦截器在方法执行前判断免登录状态

自定义注解这里命名为NoToken

java 复制代码
import java.lang.annotation.*;

/**
 * 不校验token注解
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoToken {
    String name() default "";
}

这里采用拦截器搭配使用,拦截器代码如下

java 复制代码
@Slf4j
public class SessionInterceptor implements HandlerInterceptor {

    //在请求处理之前进行调用Controller方法调用之前
    @Override
    @Reference
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            NoToken classAnno = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoToken.class);
            //获取出Controller上的NoToken注解
            if (classAnno != null) {
                // 如果注解不为null, 说明不需要拦截, 直接放过
                return true;
            } else {
                Method method = handlerMethod.getMethod();
                handlerMethod.getMethodAnnotation(NoToken.class);
                //获取出方法上的NoToken注解
                NoToken access = method.getAnnotation(NoToken.class);
                if (access != null) {
                    // 如果注解不为null, 说明不需要拦截, 直接放过
                    return true;
                }
            }
        }

        RedisService redis = (RedisService) SpringContextUtils.getBean("redisService");
        String token = request.getHeader("token");


        boolean ok = false;
        log.info("开始检验token!");
        if (!StringUtils.isEmpty(token)) {
            if (redis.exists(token)) {
                redis.expire(token, ConstantsUtil.APP_TOKEN_EXPIRE);
                log.info("token有效!");
                ok = true;
            }
        }


        if (!ok) {
            Map<String, Object> result = new HashMap<>();
            result.put("returncode","-1");
            result.put("returnmsg", "登录已过期,请重新登录");
            writeJSON(response, result);
            return ok;
        }
        return ok;

    }

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

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {

    }
    public void writeJSON(HttpServletResponse response, Object o)
            throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String JsonString = JSON.toJSONString(o);
        out.write(JsonString);
    }
}

大家看到在NoToken注解和拦截器上,做了两种处理 也就是类注解方法注解

如果注解放到方法上,该方法调用的时候就是免登录的。如果注解放到@Controller类上,那么该类下的所有请求接口,都是免登录的(是不是很方便 ~)

java 复制代码
/**
 * 类上加NoToken注解,该类下所有方法都免登录
 */
@NoToken
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {


    /**
     * 方法上单独加注解,只对该方法免登录
     */
    @NoToken
    @RequestMapping("testMethod")
    public void testMethod() {
        System.out.println("1111111111111");
    }


}

以上就是实现方式,如果觉得还有用,就点个赞吧 ~

相关推荐
a程序小傲21 分钟前
蚂蚁Java面试被问:注解的工作原理及如何自定义注解
java·开发语言·python·面试
幽络源小助理37 分钟前
SpringBoot+Vue摄影师分享社区源码 – Java项目免费下载 | 幽络源
java·vue.js·spring boot
0和1的舞者40 分钟前
《软件测试分类指南:8 大维度 + 核心要点梳理》
java·软件测试·单元测试·测试·黑盒测试·白盒测试·测试分类
TAEHENGV1 小时前
创建目标模块 Cordova 与 OpenHarmony 混合开发实战
android·java·开发语言
是一个Bug1 小时前
如何阅读JDK源码?
java·开发语言
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue健身房管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Ledison71 小时前
Springboot 3.5.7 + Springcloud 2025 升级记录
java
没有bug.的程序员1 小时前
熔断、降级、限流:高可用架构的三道防线
java·网络·jvm·微服务·架构·熔断·服务注册
派大鑫wink1 小时前
【Day15】集合框架(三):Map 接口(HashMap 底层原理 + 实战)
java·开发语言
苹果醋31 小时前
iview— Select— Option选中后有空格
运维·vue.js·spring boot·nginx·课程设计