SaToken学习笔记-02

如果排版有问题,请点击:传送门

常用的登录有关的方法

- StpUtil.logout()

作用为:当前会话注销登录

调用此方法,其实做了哪些操作呢,我们来一起看一下源码

/**
* 当前会话注销登录
*/
public static void logout() {
stpLogic.logout();
}

一开始调用了stpLogic.logout()方法


什么是stpLogic?

stpLogic是在StpUtil类中定义的一个底层的StpLogic对象

public static StpLogic stpLogic = new StpLogic("login");

并且把stpLogic的loginkey设置为login,在创建对象时会在 SaTokenManager 中记录下此 StpLogic,以便根据 LoginKey 进行查找此对象


继续进入

/**
* 当前会话注销登录
*/
public void logout() {
// 如果连token都没有,那么无需执行任何操作
String tokenValue = getTokenValue();
if(tokenValue == null) {
return;
}
// 如果打开了cookie模式,第一步,先把cookie清除掉
if(getConfig().getIsReadCookie() == true){
SaHolder.getResponse().deleteCookie(getTokenName());
}
logoutByTokenValue(tokenValue);
}

可以看到,首先取到tokenvalue的值,判断token是否为空,如果为空就直接结束,表示此用户已经为非登录状态。接着通过调用getIsReadCookie()方法返回isReadCookie的常量值,默认为true。判断如果返回的值为true则表示打开了Cookie模式,使用deleteCookie()方法通过传入的token清楚对应的Cookie。最后调用logoutByTokenValue(tokenValue);对指定的token的会话注销登录。

/**
* 指定token的会话注销登录
* @param tokenValue 指定token
*/
public void logoutByTokenValue(String tokenValue) {
// 1. 清理掉[token-最后操作时间]
clearLastActivity(tokenValue); // 2. 清理Token-Session
SaManager.getSaTokenDao().delete(splicingKeyTokenSession(tokenValue)); // 3. 尝试清除token-id键值对 (先从db中获取loginId值,如果根本查不到loginId,那么无需继续操作 )
String loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
return;
}
SaManager.getSaTokenDao().delete(splicingKeyTokenValue(tokenValue)); // $$ 通知监听器
SaManager.getSaTokenListener().doLogout(loginKey, loginId, tokenValue); // 4. 尝试清理User-Session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
SaSession session = getSessionByLoginId(loginId, false);
if(session == null) {
return;
}
session.removeTokenSign(tokenValue); // 5. 尝试注销User-Session
session.logoutByTokenSignCountToZero();
}

清除token最后操作时间,session,token和loginid的键值对信息。然后通知监听器输出用户登出的消息。清理Session上的token签名,最后调用logoutByTokenSignCountToZero()注销Session

/** 当Session上的tokenSign数量为零时,注销会话 */
public void logoutByTokenSignCountToZero() {
if (tokenSignList.size() == 0) {
logout();
}
}

至此logout()操作进行完毕,总的来说不是很复杂


- StpUtil.checkLogin()

实现功能为:检验当前会话是否已经登录, 如果未登录,则抛出异常:NotLoginException

NotLoginException异常,官方做了相关扩展:

扩展:NotLoginException 对象可通过 getLoginKey() 方法获取具体是哪个 StpLogic 抛出的异常

扩展:NotLoginException 对象可通过 getType() 方法获取具体的场景值,详细参考章节:未登录场景值

个人使用场景:

@RequestMapping("/checkLogin")
public void CheckLogin(){
try{
StpUtil.checkLogin();
System.out.println("该用户已经成功登录");
}catch (NotLoginException e)
{
System.out.println("该用户未登录");
String loginkey = e.getLoginKey();
String type = e.getType();
System.out.println("loginkey=>"+loginkey+",type=>"+type);
}
}

开始源码查看

/**
* 检验当前会话是否已经登录,如未登录,则抛出异常
*/
public static void checkLogin() {
stpLogic.checkLogin();
}

调用了stpLogic的checkLogin方法,继续深入

/**
* 检验当前会话是否已经登录,如未登录,则抛出异常
*/
public void checkLogin() {
getLoginId();
}

没什么好说的,继续点进去

/**
* 获取当前会话账号id, 如果未登录,则抛出异常
* @return 账号id
*/
public Object getLoginId() {
// 如果正在[临时身份切换], 则返回临时身份
if(isSwitch()) {
return getSwitchLoginId();
}
// 如果获取不到token,则抛出: 无token
String tokenValue = getTokenValue();
if(tokenValue == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN);
}
// 查找此token对应loginId, 如果找不到则抛出:无效token
String loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN);
}
// 如果是已经过期,则抛出已经过期
if(loginId.equals(NotLoginException.TOKEN_TIMEOUT)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.TOKEN_TIMEOUT);
}
// 如果是已经被顶替下去了, 则抛出:已被顶下线
if(loginId.equals(NotLoginException.BE_REPLACED)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.BE_REPLACED);
}
// 如果是已经被踢下线了, 则抛出:已被踢下线
if(loginId.equals(NotLoginException.KICK_OUT)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT);
}
// 检查是否已经 [临时过期]
checkActivityTimeout(tokenValue);
// 如果配置了自动续签, 则: 更新[最后操作时间]
if(getConfig().getAutoRenew()) {
updateLastActivityToNow(tokenValue);
}
// 至此,返回loginId
return loginId;
}

ok,首先判断是否正在进行临时身份切换,这个之前解析过了。之后取到当前的token值,如果找不到就抛出NotLoginException异常,如果找到了就通过token返回对应的loginId,同样判断是否loginId有值,如果没有就返回异常。之后判断是否loginId已经过期,是否已经被顶替,是否被踢下线,满足任意一项就抛出NotLoginException的异常。最后检查是否token已经过期,并且对token重新设置了最后操作时间,返回loginId。

同样没什么复杂的,下面查看异常的Instance方法做了什么

/**
* 静态方法构建一个NotLoginException
* @param loginKey loginKey
* @param type 场景类型
* @return 构建完毕的异常对象
*/
public static NotLoginException newInstance(String loginKey, String type) {
String message = null;
if(NOT_TOKEN.equals(type)) {
message = NOT_TOKEN_MESSAGE;
}
else if(INVALID_TOKEN.equals(type)) {
message = INVALID_TOKEN_MESSAGE;
}
else if(TOKEN_TIMEOUT.equals(type)) {
message = TOKEN_TIMEOUT_MESSAGE;
}
else if(BE_REPLACED.equals(type)) {
message = BE_REPLACED_MESSAGE;
}
else if(KICK_OUT.equals(type)) {
message = KICK_OUT_MESSAGE;
}
else {
message = DEFAULT_MESSAGE;
}
return new NotLoginException(message, loginKey, type);
}

不难看出通过传入的loginKey和type给变量mssage也就是错误信息赋上不同对应的错误信息。最后调用NotLoginException的构造函数传入确定的message,loginKey,type返回异常。


总体上来说,干了什么还是一目了然的,并不是很难看懂。

END

最新文章

  1. Python-6 分支 循环
  2. oracle DBlink 【转】
  3. WebView 调试
  4. Redis 安装,主从配置及Sentinel配置自动Failover
  5. 初识A*算法
  6. 有三个线程T1 T2 T3,如何保证他们按顺序执行-转载
  7. JavaScript-闭包注意事项
  8. MySQL 5.7原生JSON格式支持
  9. Java连接oracle数据库的OCI和THIN
  10. 基于野火M3开发板(STM32F103VET6)的迷宫小球(重力感应控制)游戏开发
  11. DJANGO用户名认证一例
  12. C#关于HttpClient的应用(一):获取IP所在的地理位置信息
  13. mySQL的安装和基础使用及语法教程
  14. css布局:左边固定宽度,右边自适应;右边固定宽度,左边自适应
  15. JustOj 1927: 回文串
  16. Java设计模式学习记录-建造者模式
  17. ASP.NET学习笔记(6)——jQuery的Ajax基本操作
  18. iOS开发 frame 与 bounds 的区别与关系 转自隔叶黄莺
  19. MFC数据库操作
  20. 87. 再谈变体型Variant

热门文章

  1. CentOS-查找删除历史文件
  2. XCTF reverse maze
  3. Nacos配置中心功能
  4. Java | 循环的控制语句
  5. 7.Java数组
  6. [005] - JavaSE面试题(五):String类
  7. Hive——基本DML语句
  8. Python+Scrapy+Crawlspider 爬取数据且存入MySQL数据库
  9. JavaScript实现拖放效果
  10. debian 9安装细节