引言
在 web 项目中,登录鉴权是最核心的安全机制:
接口必须校验用户是否登录、是否拥有权限,未登录则直接拦截,禁止访问。
springboot 提供的 handlerinterceptor 拦截器,是实现登录校验、日志记录、接口限流最优雅的方案。
本篇文章将介绍原理、自定义拦截器、登录校验实战、放行白名单、全局异常处理。
一、什么是拦截器?作用是什么?
拦截器(interceptor):在请求进入 controller 之前/之后/渲染完成 进行拦截处理。
核心用途:
- 登录状态校验
- 权限校验
- 接口日志记录
- 防重复提交
- 性能监控
特点:
- 只拦截 controller 请求
- 不拦截静态资源(可配置)
- 可中断请求,直接返回结果
- 全局统一控制,代码干净
二、拦截器核心 api
实现 handlerinterceptor 接口,重写 3 个方法:
publicinterfacehandlerinterceptor{
// 1. 请求进入controller之前执行(鉴权写这里)
defaultbooleanprehandle(httpservletrequest request,httpservletresponse response,object handler)throwsexception{
returntrue;// true=放行 false=拦截
}
// 2. controller执行完毕,渲染页面之前执行
defaultvoidposthandle(...)throwsexception{}
// 3. 整个请求完全结束后执行(清理资源)
defaultvoidaftercompletion(...)throwsexception{}
}登录鉴权只需要 prehandle
三、自定义登录拦截器
创建 logininterceptor.java:
importlombok.extern.slf4j.slf4j;
importorg.springframework.web.servlet.handlerinterceptor;
importjavax.servlet.http.httpservletrequest;
importjavax.servlet.http.httpservletresponse;
/**
* 登录拦截器:校验是否登录
*/
@slf4j
publicclasslogininterceptorimplementshandlerinterceptor{
// 进入controller前执行:核心校验逻辑
@override
publicbooleanprehandle(httpservletrequest request,httpservletresponse response,object handler)throwsexception{
// 1. 获取前端传递的 token / session
string token = request.getheader("token");
log.info("当前请求token:{}", token);
// 2. 判断是否登录(真实项目:查询redis/数据库)
if(token ==null|| token.isempty()){
log.error("用户未登录,请求被拦截");
// 拦截,返回未登录提示
response.setcontenttype("application/json;charset=utf-8");
response.getwriter().write("{\"code\":401,\"msg\":\"未登录,请先登录\",\"data\":null}");
returnfalse;
}
// 3. 登录有效,放行
returntrue;
}
}四、注册拦截器 + 配置白名单
创建 webconfig.java:
实现 webmvcconfigurer,注册拦截器并设置放行接口(登录、注册、放行接口)。
importorg.springframework.context.annotation.configuration;
importorg.springframework.web.servlet.config.annotation.interceptorregistry;
importorg.springframework.web.servlet.config.annotation.webmvcconfigurer;
/**
*web 配置:注册拦截器
*/
@configuration
publicclasswebconfigimplementswebmvcconfigurer{
@override
publicvoidaddinterceptors(interceptorregistry registry){
registry.addinterceptor(newlogininterceptor())
.addpathpatterns("/**")// 拦截所有请求
.excludepathpatterns(// 放行白名单
"/user/login",// 登录接口
"/user/register",// 注册接口
"/swagger/**",// 接口文档
"/v3/api-docs/**"
);
}
}✅ 配置完成,所有接口都会自动校验登录
五、配合统一返回结构
拦截器中直接返回 result 格式:
response.setcontenttype("application/json;charset=utf-8");
result result =result.fail(401,"未登录,请先登录");
response.getwriter().write(newobjectmapper().writevalueasstring(result));
returnfalse;返回格式:
{
"code":401,
"msg":"未登录,请先登录",
"data":null
}六、登录校验逻辑
真实项目中,登录逻辑一般是:
- 前端登录成功,后端生成 token
- token 存入 redis(设置过期时间)
- 前端每次请求在 请求头 header 携带 token
- 拦截器获取 token,查询 redis 是否有效
- 有效放行,无效拦截
完整版拦截器
1@slf4j
2publicclasslogininterceptorimplementshandlerinterceptor{
3
4@autowired
5privateredistemplate<string,object> redistemplate;
6
7@override
8publicbooleanprehandle(httpservletrequest request,httpservletresponse response,object handler)throwsexception{
9string token = request.getheader("token");
10
11// 1. 无token
12if(token ==null|| token.isblank()){
13returnresponsefail(response,"未登录,请先登录");
14}
15
16// 2. 校验redis
17object user = redistemplate.opsforvalue().get("login:token:"+ token);
18if(user ==null){
19returnresponsefail(response,"登录已过期,请重新登录");
20}
21
22// 3. 放行
23returntrue;
24}
25
26// 统一返回错误
27privatebooleanresponsefail(httpservletresponse response,string msg)throwsexception{
28 response.setcontenttype("application/json;charset=utf-8");
29result<?> result =result.fail(401, msg);
30 response.getwriter().write(newobjectmapper().writevalueasstring(result));
31returnfalse;
32}
33}七、拦截器常见高级用法
1. 获取当前请求接口信息
handlermethod handlermethod =(handlermethod) handler; string methodname = handlermethod.getmethod().getname(); string classname = handlermethod.getbean().getclass().getname();
2. 放行静态资源
.excludepathpatterns("/static/**","/img/**","/css/**","/js/**")3. 多拦截器顺序
registry.addinterceptor(a).order(1); registry.addinterceptor(b).order(2);
数字越小,越先执行。
八、拦截器 vs 过滤器 filter
| 组件 | 技术 | 作用范围 | 适用场景 |
|---|---|---|---|
| 拦截器 interceptor | spring | 只拦截controller | 登录、权限、日志 |
| 过滤器 filter | servlet | 所有请求 | 编码、跨域、限流 |
登录鉴权优先用拦截器!
九、总结
- 实现 handlerinterceptor
- prehandle 写登录校验
- webconfig 注册 + 白名单
- 返回 401 未登录
- 配合 redis 实现真实登录鉴权
以上就是springboot拦截器(interceptor)自定义实现登录鉴权功能的详细内容,更多关于springboot拦截器实现登录鉴权的资料请关注代码网其它相关文章!
发表评论