Code the extended usage of Sa-Token in DDD4J projects. LLMs know the standard Sa-Token API, but do not know DDD4J's StpKit extension pattern.
Why this skill is needed
LLMs will use StpUtil.getLoginId() to get the logged-in user — DDD4J requires using StpUtil.getExtra("uuid") to get the extension payload. LLMs do not know that DDD4J injects user/org/role extension parameters at login. LLMs will use SaTempUtil.createToken()— DDD4J encapsulates SaTempKit。
Capability Boundaries
✅ Strong Suits
- StpKit extension payload — inject user/org/role at login, retrieve with StpUtil.getExtra()
- SaTempKit — the one-time temporary token utility encapsulated by DDD4J
- Exception handling integration — unified handling of Sa-Token exceptions and ApiRestResponse
- Multi-account system — StpKit facade pattern distinguishes users and administrators
❌ Out of Scope
- Sa-Token basic API (login/checkPermission/annotation-based authentication) → sa-token(general skill)
- Entity/Controller/Service conventions → ddd4j-core
The most common mistakes LLMs make
| # | Mistake | Correct approach |
|---|---|---|
| 1 | StpUtil.getLoginId() to get user information |
StpUtil.getExtra("uuid") / getExtra("username") |
| 2 | Login only passes userId | Inject the extension payload (user/org/role) at login |
| 3 | SaTempUtil.createToken() |
Use SaTempKit.createToken()(encapsulated by DDD4J) |
| 4 | Directly throw Sa-Token exceptions | Integrate into GlobalExceptionHandler to return ApiRestResponse |
| 5 | StpUtil.login(userId) standard usage |
Use StpKit to specify the account system's login |
| 6 | Use the Authorization header for cross-service authentication | Use Same-Token + SaSameUtil |
Core rules quick reference
// ✅ 登录:注入扩展载荷
StpUtil.login(userId, new SaLoginParameter()
.setExtra("uuid", user.getUid()) // 用户唯一标识
.setExtra("username", user.getUserName()) // 用户名
.setExtra("orgId", user.getOrgId()) // 组织ID
.setExtra("role", user.getRoleCodes()) // 角色列表
.setExtra("realName", user.getRealName()) // 真实姓名
);
// ✅ 获取扩展载荷(而非 getLoginId)
String uuid = (String) StpUtil.getExtra("uuid");
String username = (String) StpUtil.getExtra("username");
String orgId = (String) StpUtil.getExtra("orgId");
// ✅ DDD4J 临时令牌
String token = SaTempKit.createToken(userId, 300); // 5分钟
Long id = SaTempKit.parseToken(token, Long.class);
// ✅ 跨服务鉴权
// Gateway: 注入 Same-Token
SaSameUtil.getToken();
// 子服务: 校验
SaSameUtil.checkCurrentRequestToken();
// 定时刷新(每5分钟)
@Scheduled(cron = "0 0/5 * * * ?")
public void refreshToken() { SaSameUtil.refreshToken(); }
Gotchas
- The extension payload must be injected at login — otherwise
StpUtil.getExtra()returns null - The extension payload only takes effect in JWT mode — in non-JWT mode the data is stored in Redis
- SaTempKit is encapsulated by DDD4J, not built into Sa-Token — dependency import
sa-token-temp-jwt - Same-Token has a default validity period of one day — scheduled refresh must be configured in production
- @SaCheckPermission requires the permission code to be registered in StpInterface — just adding the annotation is not enough
- Sa-Token exceptions must be uniformly converted to ApiRestResponse — handle them in GlobalExceptionHandler
Data Privacy
This skill does not collect, store, or transmit any user data.