有了 Token 令牌后,在接口请求过程中携带令牌即代表当前用户已经登录了。
而很多时候我们需要获取令牌中的用户 ID,例如在更新用户信息的场景,我们一般不会像 /user/{id}
这样直接将用户 ID 传到接口中,而是通过请求头中的 Token 来获取当前用户。
Python Flask 中有一个 flask.g
可以保存当前请求中的全局变量,例如 g.user
即可获取到当前用户。
如果 SpringBoot 也可以这样那就非常方便了。ThreadLocal 在多线程操作的时候,可以获取当前线程内存中的变量,从而规避线程安全问题。
ThreadLocal 可以通过 get
和 set
方法得到当前线程对应的值。
下面的例子是使用 ThreadLocal 实现 LocalUser:
public class LocalUser {
private static final ThreadLocal<User> local = new ThreadLocal<>();
/**
* 获得登录用户
*/
public static User getLocalUser() {
return LocalUser.local.get();
}
/**
* 设置登录用户
*/
public static void setLocalUser(User user) {
LocalUser.local.set(user);
}
/**
* 清理当前用户
*/
public static void clearLocalUser() {
LocalUser.local.remove();
}
}
视图层中直接通过 getLocalUser 即可获取当前用户
User localUser = LocalUser.getLocalUser();
在令牌成功时,则设置当前的登录用户
/**
* 验证用户
*/
private static void verifyUser(String userId) {
User user = JwtUtil.userService.getById(userId);
if (user == null) {
throw new NotFoundException();
}
LocalUser.setLocalUser(user);
}