sa-token
9
总安装量
9
周安装量
#31144
全站排名
安装命令
npx skills add https://github.com/m19803261706/springboot-vben-admin --skill sa-token
Agent 安装分布
claude-code
8
trae
7
opencode
7
antigravity
6
windsurf
6
codex
6
Skill 文档
Sa-Token å¼åè§è
æ¬é¡¹ç®ä½¿ç¨ Sa-Token 1.38+ ä½ä¸ºæéè®¤è¯æ¡æ¶ï¼åºäº Spring Boot 4 éæã
ææ¯æ
| ææ¯ | çæ¬ | ç¨é |
|---|---|---|
| Sa-Token | 1.38+ | æéè®¤è¯æ¡æ¶ |
| Spring Boot | 4.0.1 | åç«¯æ¡æ¶ |
| Redis | – | Token æä¹ åï¼å¯éï¼ |
Maven ä¾èµ
<!-- Sa-Token Spring Boot 3.x Starter -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.38.0</version>
</dependency>
<!-- Sa-Token æ´å JWT (å¯é) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.38.0</version>
</dependency>
é ç½®æä»¶
# application.yml
sa-token:
# Token åç§° (忶乿¯ Cookie åç§°)
token-name: Authorization
# Token æææ (åä½ï¼ç§)ï¼é»è®¤30天ï¼-1 代表永ä¹
ææ
timeout: 2592000
# Token ä¸´æ¶æææ (æå®æ¶é´å
æ æä½å°±è§ä¸º Token è¿æ)
active-timeout: -1
# æ¯å¦å
许åä¸è´¦å·å¤å°åæ¶ç»å½
is-concurrent: true
# å¨å¤äººç»å½åä¸è´¦å·æ¶ï¼æ¯å¦å
±ç¨ä¸ä¸ª Token
is-share: false
# Token 飿 ¼ (uuid/simple-uuid/random-32/random-64/random-128/tik)
token-style: uuid
# æ¯å¦è¾åºæä½æ¥å¿
is-log: true
# æ¯å¦ä» Cookie ä¸è¯»å Token
is-read-cookie: false
# æ¯å¦ä» Header ä¸è¯»å Token
is-read-header: true
# Token åç¼
token-prefix: Bearer
æ ¸å¿ä»£ç 模æ¿
1. StpInterface å®ç° (æéæ°æ®æº)
package com.example.security;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* Sa-Token æéè®¤è¯æ¥å£å®ç°
* ç¨äºè·åç¨æ·çæéå表åè§è²å表
*/
@Component
public class StpInterfaceImpl implements StpInterface {
private final SysUserService userService;
private final SysRoleService roleService;
private final SysMenuService menuService;
public StpInterfaceImpl(SysUserService userService,
SysRoleService roleService,
SysMenuService menuService) {
this.userService = userService;
this.roleService = roleService;
this.menuService = menuService;
}
/**
* è¿åæå®è´¦å·æ¥æçæéç éå
* @param loginId ç»å½ç¨æ·ID
* @param loginType ç»å½ç±»å
* @return æéç å表
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
Long userId = Long.parseLong(loginId.toString());
// 仿°æ®åºæ¥è¯¢ç¨æ·æé
return menuService.selectPermsByUserId(userId);
}
/**
* è¿åæå®è´¦å·æ¥æçè§è²æ è¯éå
* @param loginId ç»å½ç¨æ·ID
* @param loginType ç»å½ç±»å
* @return è§è²æ è¯å表
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
Long userId = Long.parseLong(loginId.toString());
// 仿°æ®åºæ¥è¯¢ç¨æ·è§è²
return roleService.selectRoleCodesByUserId(userId);
}
}
2. ç»å½è®¤è¯æå¡
package com.example.service;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import org.springframework.stereotype.Service;
/**
* è®¤è¯æå¡
*/
@Service
public class AuthService {
private final SysUserService userService;
private final PasswordEncoder passwordEncoder;
public AuthService(SysUserService userService, PasswordEncoder passwordEncoder) {
this.userService = userService;
this.passwordEncoder = passwordEncoder;
}
/**
* ç¨æ·ç»å½
* @param username ç¨æ·å
* @param password å¯ç
* @return Token ä¿¡æ¯
*/
public SaTokenInfo login(String username, String password) {
// 1. æ¥è¯¢ç¨æ·
SysUser user = userService.findByUsername(username);
if (user == null) {
throw new RuntimeException("ç¨æ·ä¸åå¨");
}
// 2. éªè¯å¯ç
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new RuntimeException("å¯ç é误");
}
// 3. æ£æ¥ç¶æ
if (user.getStatus() != 1) {
throw new RuntimeException("è´¦å·å·²è¢«ç¦ç¨");
}
// 4. æ§è¡ç»å½
StpUtil.login(user.getId());
// 5. è¿å Token ä¿¡æ¯
return StpUtil.getTokenInfo();
}
/**
* ç¨æ·ç»åº
*/
public void logout() {
StpUtil.logout();
}
/**
* è·åå½åç»å½ç¨æ·ID
* @return ç¨æ·ID
*/
public Long getCurrentUserId() {
return StpUtil.getLoginIdAsLong();
}
/**
* è·åå½åç»å½ç¨æ·ä¿¡æ¯
* @return ç¨æ·ä¿¡æ¯
*/
public SysUser getCurrentUser() {
Long userId = getCurrentUserId();
return userService.findById(userId);
}
}
3. æé注解使ç¨
package com.example.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.annotation.SaMode;
import org.springframework.web.bind.annotation.*;
/**
* ç¨æ·ç®¡çæ§å¶å¨
*/
@RestController
@RequestMapping("/api/sys/user")
@SaCheckLogin // æ´ä¸ªæ§å¶å¨éè¦ç»å½
public class SysUserController {
/**
* è·åç¨æ·å表 - éè¦ sys:user:list æé
*/
@GetMapping
@SaCheckPermission("sys:user:list")
public Result<Page<SysUser>> list(SysUserQuery query) {
return Result.success(userService.page(query));
}
/**
* æ°å¢ç¨æ· - éè¦ sys:user:add æé
*/
@PostMapping
@SaCheckPermission("sys:user:add")
public Result<Void> add(@RequestBody SysUser user) {
userService.save(user);
return Result.success();
}
/**
* æ´æ°ç¨æ· - éè¦ sys:user:edit æé
*/
@PutMapping("/{id}")
@SaCheckPermission("sys:user:edit")
public Result<Void> update(@PathVariable Long id, @RequestBody SysUser user) {
user.setId(id);
userService.update(user);
return Result.success();
}
/**
* å é¤ç¨æ· - éè¦ sys:user:delete æéæ admin è§è²
*/
@DeleteMapping("/{id}")
@SaCheckPermission(value = "sys:user:delete", orRole = "admin")
public Result<Void> delete(@PathVariable Long id) {
userService.delete(id);
return Result.success();
}
/**
* æ¹éæä½ - éè¦åæ¶å
·å¤å¤ä¸ªæé
*/
@PostMapping("/batch")
@SaCheckPermission(value = {"sys:user:add", "sys:user:edit"}, mode = SaMode.AND)
public Result<Void> batch(@RequestBody BatchRequest request) {
userService.batch(request);
return Result.success();
}
/**
* è§è²æ ¡éª - éè¦ admin è§è²
*/
@GetMapping("/admin-only")
@SaCheckRole("admin")
public Result<String> adminOnly() {
return Result.success("Admin access granted");
}
/**
* 忽ç¥è®¤è¯ - å
¬å¼æ¥å£
*/
@SaIgnore
@GetMapping("/public")
public Result<String> publicApi() {
return Result.success("Public API");
}
}
4. å ¨å±å¼å¸¸å¤ç
package com.example.config;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* Sa-Token å¼å¸¸å¤ç
*/
@RestControllerAdvice
public class SaTokenExceptionHandler {
/**
* æªç»å½å¼å¸¸
*/
@ExceptionHandler(NotLoginException.class)
public Result<Void> handleNotLogin(NotLoginException e) {
String message = switch (e.getType()) {
case NotLoginException.NOT_TOKEN -> "æªæä¾Token";
case NotLoginException.INVALID_TOKEN -> "Tokenæ æ";
case NotLoginException.TOKEN_TIMEOUT -> "Tokenå·²è¿æ";
case NotLoginException.BE_REPLACED -> "è´¦å·å·²å¨å
¶ä»å°æ¹ç»å½";
case NotLoginException.KICK_OUT -> "è´¦å·å·²è¢«è¸¢ä¸çº¿";
default -> "æªç»å½";
};
return Result.fail(401, message);
}
/**
* æ æéå¼å¸¸
*/
@ExceptionHandler(NotPermissionException.class)
public Result<Void> handleNotPermission(NotPermissionException e) {
return Result.fail(403, "æ æé: " + e.getPermission());
}
/**
* æ è§è²å¼å¸¸
*/
@ExceptionHandler(NotRoleException.class)
public Result<Void> handleNotRole(NotRoleException e) {
return Result.fail(403, "æ è§è²: " + e.getRole());
}
}
5. Sa-Token é 置类
package com.example.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;
/**
* Sa-Token é
ç½®
*/
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注å Sa-Token æ¦æªå¨
registry.addInterceptor(new SaInterceptor(handle -> {
// æå®æ¦æªè·¯ç±
SaRouter.match("/**")
// æé¤ç»å½ã注åçå
¬å¼æ¥å£
.notMatch("/api/auth/login", "/api/auth/register")
// æé¤éæèµæº
.notMatch("/static/**", "/favicon.ico")
// æ ¡éªç»å½
.check(r -> StpUtil.checkLogin());
})).addPathPatterns("/**");
}
}
æéæ è¯è§è
{模å}:{å®ä½}:{æä½}
示ä¾ï¼
sys:user:list - ç¨æ·å表
sys:user:add - æ°å¢ç¨æ·
sys:user:edit - ç¼è¾ç¨æ·
sys:user:delete - å é¤ç¨æ·
sys:role:list - è§è²å表
sys:menu:list - èåå表
å¸¸ç¨ API
| API | 说æ |
|---|---|
StpUtil.login(id) |
ç»å½ |
StpUtil.logout() |
ç»åº |
StpUtil.isLogin() |
æ¯å¦å·²ç»å½ |
StpUtil.checkLogin() |
æ ¡éªç»å½ï¼æªç»å½æå¼å¸¸ï¼ |
StpUtil.getLoginId() |
è·åç»å½ID |
StpUtil.getLoginIdAsLong() |
è·åç»å½ID (Long) |
StpUtil.getTokenInfo() |
è·åTokenä¿¡æ¯ |
StpUtil.hasPermission(perm) |
æ¯å¦ææé |
StpUtil.checkPermission(perm) |
æ ¡éªæé |
StpUtil.hasRole(role) |
æ¯å¦æè§è² |
StpUtil.checkRole(role) |
æ ¡éªè§è² |
StpUtil.kickout(id) |
踢人ä¸çº¿ |
æä½³å®è·µ
- Token åå¨: ç产ç¯å¢å»ºè®®ä½¿ç¨ Redis åå¨ Token
- æéç¼å: å¯å¨ StpInterface ä¸å®ç°æéç¼åæåæ§è½
- 注解ä¼å : ä¼å ä½¿ç¨æ³¨è§£æ¹å¼è¿è¡æéæ ¡éª
- ç»ä¸å¼å¸¸: é ç½®å ¨å±å¼å¸¸å¤çå¨å¤ç认è¯å¼å¸¸
- æ¥å£åå±: å ¬å¼æ¥å£ä½¿ç¨ @SaIgnoreï¼æææ¥å£ä½¿ç¨æé注解
Context7 Library: /dromara/sa-token å建æ¶é´: 2026-01-13