SpringBoot中集成SaToken
SpringBoot中集成SaToken
- 1. 写一个拦截器
- 2. 对拦截器的说明&解释
- 2. 拦截器
1. 写一个拦截器
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* SaToken拦截器
* <p>
* 该类的作用是在请求处理前进行权限认证,以确保只有登录用户可以访问受保护的资源
* 它通过实现HandlerInterceptor接口,使用Spring框架提供的拦截器机制来实现功能
* <p>
* href:https://sa-token.cc/doc.html#/
*
*/
@Component
public class SaTokenInterceptor implements HandlerInterceptor {
/**
* 一键控制权限认证开关
*/
@Value("${sa-token.is-auth}")
private boolean isAuth;
/**
* 在请求处理前进行权限认证
* <p>
* 如果权限认证开关打开,该方法会检查用户是否已登录
*
* @param request 用于获取请求信息
* @param response 用于向客户端返回信息
* @param handler 当前处理请求的处理器
* @return 如果权限认证通过或未启用权限认证,返回true,继续执行后续的请求处理;否则返回false,中断请求处理
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (isAuth) {
try {
// 如果权限认证开启,校验登录状态
StpUtil.checkLogin();
} catch (NotLoginException e) {
// 捕获未登录或 Token 过期的异常,通知前端跳转
response.setContentType("application/json;charset=UTF-8");
// 这里设置4001 未授权
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"code\":4001, \"message\":\"未登录或登录已过期\", \"redirect\":\"/auth/inner-login\"}");
return false;
}
}
return true;
}
}
saToken的pom依赖
<!-- Sa-Token权限认证,在线文档:https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.39.0</version>
</dependency>
application-dev.yml的配置
# 权限认证框架
sa-token:
# 一键控制权限认证开关
is-auth: true
token-name: token
# Token 有效期(秒)
timeout: 2592000
# 是否允许同一账号多地同时登录
is-concurrent: true
# token风格
token-style: uuid
# 是否输出操作日志
is-log: true
# 不读取cookie,防止Cookie帮你自动提交Token
is-read-cookie: true
2. 对拦截器的说明&解释
这段代码定义了一个 SaTokenInterceptor 类,它是一个 Spring MVC 的拦截器,用于处理权限认证。拦截器的功能是确保只有已登录的用户能够访问某些受保护的资源。下面是对代码的详细解释:
1.导入的依赖
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
- NotLoginException: 这是 Sa-Token 框架中的一个异常,表示用户没有登录或登录状态已过期。
- StpUtil: Sa-Token 提供的工具类,包含了处理登录、权限等功能的方法。
- @Value: 用于注入配置文件中的属性。
- HandlerInterceptor: Spring Web 提供的拦截器接口,用于在请求处理之前、之后或完成时进行拦截和处理。
2.SaTokenInterceptor 类的声明
@Component
public class SaTokenInterceptor implements HandlerInterceptor
- @Component: 该注解使得 SaTokenInterceptor 成为 Spring 容器管理的 Bean,能够自动注入到 Spring 的上下文中。
- 实现 HandlerInterceptor 接口: 通过实现 preHandle 方法,我们可以在请求被处理前进行认证。
3.成员变量:权限开关
@Value("${sa-token.is-auth}")
private boolean isAuth;
@Value("${sa-token.is-auth}"): 从 application.properties
或application.yml
配置文件中读取sa-token.is-auth
的值并赋给isAuth
。该配置项控制是否启用权限认证。- 如果 isAuth 为 true,则进行权限认证。
- 如果 isAuth 为 false,则跳过权限认证。
4.preHandle 方法:请求前权限认证
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (isAuth) {
try {
// 如果权限认证开启,校验登录状态
StpUtil.checkLogin();
} catch (NotLoginException e) {
// 捕获未登录或 Token 过期的异常,通知前端跳转
response.setContentType("application/json;charset=UTF-8");
// 这里设置4001 未授权
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"code\":4001, \"message\":\"未登录或登录已过期\", \"redirect\":\"/auth/inner-login\"}");
return false;
}
}
return true;
}
preHandle
方法: 这是HandlerInterceptor
接口中的一个方法,它在请求处理之前被调用。它可以用来做权限认证、日志记录等操作。如果返回 true,请求会继续向下执行;如果返回 false,则请求会被中断。
2. 拦截器
当然配置了权限肯定也要配置拦截器
import cn.ac.ict.knowledge.graph.common.interceptor.SaTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 自动注入SaTokenInterceptor,用于拦截请求进行权限验证等操作
*/
@Autowired
private SaTokenInterceptor saTokenInterceptor;
/**
* 添加拦截器配置
* 此方法用于向Spring MVC框架注册拦截器,并指定拦截器的拦截路径
*
* @param registry 拦截器注册器,用于注册自定义拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 除登陆、注册接口,拦截所有接口
registry.addInterceptor(saTokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/auth/inner-login",
"/auth/inner-update",
"/menu/get",
"/swagger-ui.html",
"/v3/api-docs/**",
"/swagger-resources/**",
"/webjars/**",
"/doc.html",
"/v*/api-docs**");
}
}
其实上面应该也要根据是否开启权限判断,是否使用拦截器
if (isAuth) { // 根据配置判断是否启用拦截器
registry.addInterceptor(saTokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/auth/inner-login", "/auth/inner-update", "/menu/get",
"/swagger-ui.html", "/v3/api-docs/**", "/swagger-resources/**",
"/webjars/**", "/doc.html", "/v*/api-docs**");
}