如果你想在 JWT Token 里面存入姓名、年龄、身高等信息,你需要在 login
时使用 Sa-Token 的自定义 Token 数据 功能,把这些额外信息编码进 Token 里。
🔥 1. 在 Token 里存储用户信息
在 login
时,除了存 userId
,还可以额外存储用户信息,比如 name
、age
、height
。
✅ 修改登录接口,把用户信息编码进 Token
@PostMapping("/login")
public SaResult login(@RequestParam String username, @RequestParam String password) {
// 1. 查询用户信息
User user = userService.getByUsername(username);
if (user == null || !password.equals(user.getPassword())) {
return SaResult.error("用户名或密码错误");
}
// 2. 生成 Token(JWT)
StpUtil.login(user.getId());
// 3. 获取 JWT 构造器
SaJwtUtil jwtUtil = SaManager.getSaTokenContextOrThrow().getJwtUtil();
// 4. 自定义 Token 载荷(将用户信息存入 Token)
String token = jwtUtil.createToken(Map.of(
"loginId", user.getId(),
"name", user.getName(),
"age", user.getAge(),
"height", user.getHeight()
));
return SaResult.ok("登录成功").set("token", token);
}
这一步的关键
登录后,获取 Sa-Token 的 JWT 工具类
使用
createToken()
自定义 Token 载荷(存入姓名、年龄、身高等信息)返回这个 Token 给前端
🔥 2. 解析 JWT,获取用户信息
用户请求时,你需要解析 Token,获取存入的 name
、age
、height
信息。
✅ 在网关解析 Token 并透传信息
@Component
public class JwtAuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (token == null || !token.startsWith("Bearer ")) {
return unauthorized(exchange, "未登录");
}
token = token.replace("Bearer ", "");
try {
// 解析 JWT
SaJwtUtil jwtUtil = SaManager.getSaTokenContextOrThrow().getJwtUtil();
SaJwtPayload payload = jwtUtil.parseToken(token);
// 读取 Token 里的自定义信息
String userId = payload.getString("loginId");
String name = payload.getString("name");
int age = payload.getInt("age");
double height = payload.getDouble("height");
// 透传用户信息给后端微服务
ServerHttpRequest newRequest = request.mutate()
.header("X-User-Id", userId)
.header("X-User-Name", name)
.header("X-User-Age", String.valueOf(age))
.header("X-User-Height", String.valueOf(height))
.build();
return chain.filter(exchange.mutate().request(newRequest).build());
} catch (Exception e) {
return unauthorized(exchange, "Token 无效");
}
}
private Mono<Void> unauthorized(ServerWebExchange exchange, String message) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return -100;
}
}
📌 网关解析 Token 并透传用户信息
从 JWT 里解析
name
、age
、height
将这些信息放入请求头(
X-User-Name
、X-User-Age
)后端微服务直接读取请求头,获取用户信息
🔥 3. 后端微服务如何获取用户信息?
在微服务里,直接从 Request Header
读取 name
、age
、height
,无需解析 JWT
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/info")
public SaResult getUserInfo(
@RequestHeader("X-User-Id") String userId,
@RequestHeader("X-User-Name") String name,
@RequestHeader("X-User-Age") int age,
@RequestHeader("X-User-Height") double height
) {
return SaResult.ok()
.set("userId", userId)
.set("name", name)
.set("age", age)
.set("height", height);
}
}
📌 后端微服务无需解析 JWT,只要读取请求头即可!🚀
🔥 4. 结论
JWT 里存入用户信息(
name
、age
、height
)网关解析 JWT 并将这些信息透传给后端微服务
后端微服务直接读取请求头,获取用户信息
完全无状态,后端不依赖 Redis,也不用查询数据库 🚀
这样,你的系统在**无状态(Stateless)**的情况下,就能携带完整的用户信息了!🔥