关于Sa-token过程的一些解析
1.Sa-Token是什么?
Sa-Token 是一个基于 Java 的轻量级身份认证和授权框架,用于简化和加强应用程序的用户认证和权限管理功能。它提供了一套简洁的 API,使开发者可以轻松地实现用户登录、权限验证、会话管理等功能。
2.如何生成token?
根据用户id生成一串token字符串(一般来讲),根据这个已经够用。
3.c端登录流程
3.1
首先用户使用 StpUtil.login() 方法进行登录,此登录方法会根据其中一个参数-用户id生成一串token标识。
3.2
接下来让我们看一下此登录方式的登录参数有哪些以及具体含义:
1)Object id -- 这个参数表示的是用户的唯一标识id。
2)SaLoginModel loginModel -- 这个参数是登录参数模型:用于在用户登录时传递登录相关的参数。具体来说,SaLoginModel 中包含了一些用于定制登录行为的属性,主要包括以下参数:
1.isLasting:布尔值,表示用户是否持久化登录,即是否记住登录状态。若设置为 true,则用户在下次登录时无需重新输入用户名和密码,直接使用上次生成的 Token 进行登录。
2.device:字符串,表示用户登录的设备标识,用于支持多端登录。例如可以在不同设备上使用不同的标识进行登录,从而实现多端登录的控制。
3.timeout:长整型,表示 Token 超时时间,单位为秒。通过设置该值,可以控制 Token 的有效期时长,超时后需要重新登录。
通过 SaLoginModel 中的这些参数,你可以灵活地定制用户的登录行为,例如实现记住登录、多端登录控制等功能。在调用 public static void login(Object id, SaLoginModel loginModel)
方法时,可以传入一个 SaLoginModel 的实例,从而实现对登录行为的定制控制。
3)登录参数模型也可以这样写:
new SaLoginModel().setDevice(device).setExtra("name", saBaseLoginUser.getName())
完整的如下:
StpUtil.login(saBaseLoginUser.getId(), new SaLoginModel().setDevice(device).setExtra("name", saBaseLoginUser.getName()));
获取额外参数:
String name = StpClientUtil.getLoginExtra("name");
这里面的 setExtra 是指可以在参数模型里面添加额外参数,这里的额外参数是指除了用户 ID 以外,附加存储在 Token 中的一些用户相关的信息。这些额外参数可以是任何对象或者值,用于存储一些与用户相关的自定义数据,例如用户的角色、姓名、手机号码等。
3.3
token存储:存储在session中,需要后台返回给前台,当然在Sa-Token里面会自动刷新token覆盖旧的tokne。
3.4
token获取方式:
1)获取用户信息:
stpLogic.getTokenSession().get("loginUser");
2)获取token的值:
StpUtil.getTokenInfo().tokenValue;
3)其他可参照官方文档进行了解:https://sa-token.dev33.cn
4.附加一个解释:通常情况下,Sa-Token 生成的 Token 会放置在 HTTP 响应的头部中,具体使用的头部字段通常是 Authorization
,例如:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwidXNlcm5hbWUiOiJhZG1pbiJ9.CnST7UHe5j98Y3bkHf_N_vwzQt0qroKadVTnXJF9qIw
5.登陆之后获取用户信息的流程解析:
5.1
注解:@SaClientCheckLogin:此注解可以在后台接收到请求的时候,先检查请求中是否有token,如果不存在 Token 或 Token 无效,则会抛出 NotLoginException
异常。没有异常的话就可以进入到方法层获取用户信息。
5.2
在用户登陆的时候,我们可以将用户信息存储在Sa-Token的session里面,并设置好有效时间-可以在配置文件里面设置,比如:sa-token.timeout=2592000
StpClientUtil.getTokenSession().set("loginUser", saBaseClientLoginUser);
StpClientUtil.getTokenSession().get("loginUser");
6.@SaClientCheckLogin 注解:可以作为拦截器使用,小程序端拦截请求验证登录。使用他就可以不用再配置参数解析器或者拦截器了。但是要注意的是:这个注解只是判断,而非可以直接获取token里面的id,如果需要,可以采取 Sa-Token 里面自带的方法
stpLogic.getLoginId()
进行获取;如果不使用此注解,那就自己写一个LoginUser更合适,总之不是很建议使用拦截器,也不建议此注解之后再加个参数解析器。
7.这是我突然想到的办法:使用 @SaClientCheckLogin 注解拦截判断之后,在方法里面使用 stpLogic.getLoginId() 获取到id之后,将之储存在全局变量里面,并使用redis进行长久保存,这样我们不必使用注解,也不必每次都重新获取一遍id了,yeah!
全局设置以下为例:
@Component // 会被spring容器扫描、识别、管理,相当于是个组件,使用时必须引用此类,但随着数据重启会被初始化
public class PropertyFeeEntity {
// 放到缓存里面的时候可以直接放,也可以使用代值进行双重保护
private static final String LOGIN_ID = "id"; // 单价
@Resource
private RedisTemplate<String, Object> redisTemplate;
public void setId(Object value) {
redisTemplate.opsForValue().set(LOGIN_ID, value);
}
public BigDecimal getId() {
Object value = redisTemplate.opsForValue().get(PROPERTY_FEE_KEY);
if (value != null && value instanceof Integer) {
return (Integer) value;
}
return 0; // 默认值
}
}