一、sa-token 是干什么的?
sa-token 是一个 java 认证授权框架,负责:
┌────────────┬───────────────────────────────────────────────────────┐ │ 功能 │ 说明 │ ├────────────┼───────────────────────────────────────────────────────┤ │ 登录认证 │ 用户输入账号密码 → 签发 token → 后续请求带 token 访问 │ ├────────────┼───────────────────────────────────────────────────────┤ │ 权限校验 │ 判断用户是否有某个权限或角色 │ ├────────────┼───────────────────────────────────────────────────────┤ │ token 管理 │ token 的生成、存储、过期、续期 │ ├────────────┼───────────────────────────────────────────────────────┤ │ 拦截器 │ 自动拦截未登录的请求,返回 401 │ └────────────┴───────────────────────────────────────────────────────┘
jwt(json web token)是一种 token 格式。sa-token 默认用随机字符串做 token,也可以换成 jwt 格式。
二、你的项目中用了 sa-token 会变成什么样
改造前(现在)
- post /api/users → 任何人都能访问,不用登录
- get /api/users/1 → 任何人都能查
- get /api/users/1/avatar → 任何人都能下载
改造后
- post /api/users/login → 登录接口,返回 token
- get /api/users/1 → 需要携带 token 才能访问
header: authorization: token值 - delete /api/users/1 → 需要管理员权限才能删
三、集成步骤
3.1 pom.xml 加依赖
<!-- sa-token 核心 -->
<dependency>
<groupid>cn.dev33</groupid>
<artifactid>sa-token-spring-boot3-starter</artifactid>
<version>1.39.0</version>
</dependency>
<!-- sa-token 集成 redis(共享 token 信息,可选) -->
<dependency>
<groupid>cn.dev33</groupid>
<artifactid>sa-token-redis-jackson</artifactid>
<version>1.39.0</version>
</dependency>
<!-- sa-token 集成 jwt -->
<dependency>
<groupid>cn.dev33</groupid>
<artifactid>sa-token-jwt</artifactid>
<version>1.39.0</version>
</dependency>3.2 application.yml 配置
############## sa-token 配置 ############## sa-token: # token 名称(同时也是 cookie 名称) token-name: authorization # token 有效期(秒),7天 timeout: 604800 # 是否允许同一账号同时在线 is-concurrent: true # 是否允许同一账号多地登录 is-share: true # token 风格(可选:uuid、simple-uuid、random-32、random-64、random-128) token-style: uuid # 是否输出操作日志 is-log: true 配置 jwt jwt: 签名密钥,随便写一段字符串 secret-key: abcdefghijklmnopqrstuvwxyz0123456789 token 签发者 issuer: test-project
3.3 satokenconfig.java — 配置拦截器
新建文件:src/main/java/com/test/config/satokenconfig.java
package com.test.config;
import cn.dev33.satoken.interceptor.sainterceptor;
import cn.dev33.satoken.router.sarouter;
import cn.dev33.satoken.stp.stputil;
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 satokenconfig implements webmvcconfigurer {
@override
public void addinterceptors(interceptorregistry registry) {
// 注册 sa-token 拦截器
registry.addinterceptor(new sainterceptor(handle -> {
// 登录校验:需要登录才能访问的路径
sarouter.match("/api/**")
.notmatch("/api/users/login")
.notmatch("/api/users/register")
.check(r -> stputil.checklogin());
// 角色校验示例:只有 admin 才能删除用户
sarouter.match("/api/users/**", r -&gt; {
if (handle.getrequest().getmethod().equals("delete")) {
stputil.checkrole("admin");
}
});
})).addpathpatterns("/**");
}
}3.4 修改 usercontroller.java — 加登录接口
// ========== 登录 ==========
@postmapping("/login")
public map<string, object> login(@requestbody map<string, string> params) {
string username = params.get("username");
string password = params.get("password");
// 校验账号密码
user user = userservice.getuserbyusername(username);
if (user == null || !user.getpassword().equals(password)) {
return map.of("success", false, "message", "用户名或密码错误");
}
// 登录,生成 token
stputil.login(user.getid());
string tokenvalue = stputil.gettokenvalue();
return map.of("success", true, "message", "登录成功", "token", tokenvalue, "user", user);
}
@getmapping("/logout")
public map<string, object> logout() {
stputil.logout();
return map.of("success", true, "message", "退出成功");
}
// 查看当前登录的用户信息
@getmapping("/me")
public map<string, object> me() {
long userid = stputil.getloginidaslong();
user user = userservice.getuserbyid(userid);
return map.of("success", true, "user", user);
}四、jwt 在 sa-token 中的角色
登录成功 ↓ stputil.login(用户id) ↓ sa-token 生成 token ↓ 默认:随机字符串格式 → "d8f9a0e1-2b3c-4d5e-..." jwt:令牌格式 → "eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9..." ↓ 返回给前端 ↓ 前端每次请求携带此 token
jwt 的好处:token 本身包含了用户信息(用户id、过期时间等),服务端不需要查数据库或 redis 就能验证身份。
五、业务代码中如何使用
5.1 获取当前登录用户
// 在 controller 或 service 中 long userid = stputil.getloginidaslong(); // 获取当前登录的用户id user user = userservice.getuserbyid(userid);
5.2 校验权限
// 判断是否登录
stputil.islogin() // true/false
stputil.checklogin() // 未登录会抛出异常,返回 401
// 判断角色
stputil.hasrole("admin") // true/false
stputil.checkrole("admin") // 没有会抛出异常
// 判断权限
stputil.haspermission("user:delete") // true/false5.3 设置用户角色和权限
在登录时或 user 实体中定义:
// 在登录成功后给用户分配角色
stputil.login(userid);
stputil.gettokensession().set("role", "admin");六、前端请求方式
# 1. 登录获取 token
curl -x post http://localhost:8080/api/users/login \
-h "content-type: application/json" \
-d '{"username":"admin","password":"123456"}'
返回:
{"success":true,"token":"eyjhbgcioijiuzi1niis...","user":{...}}
2. 后续请求携带 token
curl http://localhost:8080/api/users/1
-h "authorization: eyjhbgcioijiuzi1niis..."
3. 查看个人信息
curl http://localhost:8080/api/users/me
-h "authorization: eyjhbgcioijiuzi1niis..."七、注意事项
1. 密码不要明文存
你现在的数据库里密码是明文 123456,生产环境要用加密:
// 注册时加密 string encodedpassword = bcrypt.gensalt().encode(password); // 登录时校验 boolean matches = bcrypt.checkpw(inputpassword, user.getpassword());
2. 密码在返回时要隐藏
// 序列化时忽略密码字段 @jsonignore private string password;
3. 拦截器配置要合理
- /api/users/login → 不拦截(要登录)
- /api/users/register → 不拦截(要注册)
- /api/** → 拦截(需要登录)
- /api/admin/** → 拦截(需要管理员角色)
八、总结
┌───────────────┬────────────────────────────────────────────────┐ │ 组件 │ 在这个项目中的作用 │ ├───────────────┼────────────────────────────────────────────────┤ │ sa-token │ 登录认证、token 管理、权限校验、请求拦截 │ ├───────────────┼────────────────────────────────────────────────┤ │ jwt │ token 的格式标准(用户信息编码在 token 中) │ ├───────────────┼────────────────────────────────────────────────┤ │ sainterceptor │ 自动拦截未登录请求,不用每个 controller 写判断 │ ├───────────────┼────────────────────────────────────────────────┤ │ stputil │ 核心工具类,登录/登出/获取用户/校验权限 │ └───────────────┴────────────────────────────────────────────────┘
到此这篇关于sa-token+jwt集成到spring boot完整指南的文章就介绍到这了,更多相关sa-token+jwt集成到spring boot内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论