Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StpLogicJwtForMixin+jwt+redis,调用注销函数logout()无效 #362

Closed
ddxl123 opened this issue Jan 2, 2023 · 10 comments
Closed

StpLogicJwtForMixin+jwt+redis,调用注销函数logout()无效 #362

ddxl123 opened this issue Jan 2, 2023 · 10 comments

Comments

@ddxl123
Copy link

ddxl123 commented Jan 2, 2023

使用版本:

implementation("cn.dev33:sa-token-spring-boot-starter:1.33.0")
implementation("cn.dev33:sa-token-jwt:1.33.0")
implementation("cn.dev33:sa-token-dao-redis:1.33.0")

涉及的功能模块:

yml:

  redis:
    host: 127.0.0.1
    port: 6379
    # Redis数据库索引(默认为0)
    database: 0
    # 读取超时时间
    timeout: 30s
    # 连接超时时间
    connect-timeout: 30s
sa-token:
  # token名称 (同时也是cookie名称),会自动从请求头根据 token-name key,获取 value
  token-name: token
  # token value 的前缀
  token-prefix: Bearer
  # token有效期,单位s 默认30天, -1代表永不过期
  timeout: -1
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: true
  # jwt 密钥
  jwt-secret-key: longjwtsecretkey1111
sa-token 
jwt 
redis 
StpLogicJwtForMixin
StpUtil.login(user_id)
StpUtil.logout()

测试步骤:

postman

  1. StpUtil.login(user_id) 进行登录。
  2. postman 加上请求头:token: Bearer xxxx.xxx.xxx,请求注销当前会话。
        StpUtil.checkLogin() // 通过。
        StpUtil.logout() 
        StpUtil.checkLogin() // 仍然通过。

为什么logout注销了,还是检测到已登录?并且,redistoken并没有被清除。
再就,手动把redistoken删除,StpUtil.checkLogin() 仍然不会抛出未登录异常。

看了源码:

StpLogicJwtForMixin中,logout()没有被标记 [禁用],
但是 logout(Object loginId, String device) 却被标记为 [禁用]。
logout() 源码中的注释有一行 // ...,这就令人好奇了,其他地方都没有这样子的注释,就这个函数带有这个注释,
不知道是我使用问题,还是 logout() 没有完善问题...
IDEA debug模式调试了下,发现StpLogicJwtForMixinlogout()函数内部的一系列调用,并没有任何涉及Redis相关内容,
好像logout()源码里并不存在对redis进行清除或修改的操作。

StpLogicJwtForMixin 源码

	/**
	 * 会话注销 
	 */
	@Override
	public void logout() {
		// ... 

 		// 从当前 [storage存储器] 里删除 
 		SaHolder.getStorage().delete(splicingKeyJustCreatedSave());
 		
 		// 如果打开了Cookie模式,则把cookie清除掉 
 		if(getConfig().getIsReadCookie()){
 			SaHolder.getResponse().deleteCookie(getTokenName());
		}
	}

这有两个相似问题,但是没有结果:#277 #188

@click33
Copy link
Collaborator

click33 commented Jan 2, 2023

你前端是怎么提交token的?

@ddxl123
Copy link
Author

ddxl123 commented Jan 2, 2023

2. postman 加上请求头:token: Bearer xxxx.xxx.xxx,请求注销当前会话。

postman 加上请求头:token: Bearer xxxx.xxx.xxx,请求注销当前会话。

@click33
Copy link
Collaborator

click33 commented Jan 2, 2023

为什么logout注销了,还是检测到已登录?并且,redis的token并没有被清除。

答:不光不会清除,而且 Mixin 模式根本就不会产生 token,你看到的 redis 中的 token 应该是使用其它模式时登录产生的,mixin 模式只会产生 session 数据,token 是 jwt 构建的,不存入 redis

注销时只会清除前端的 cookie 数据,如果你是通过请求头提交 token 的,那注销动作则不会有任何操作。
想要注销的话,就前端自己清除数据就行了

image

@ddxl123
Copy link
Author

ddxl123 commented Jan 2, 2023

@click33
所以,混入模式下,注销下线的logout操作,只对浏览器有效果,对前后端分离业务没效果吗?

@click33
Copy link
Collaborator

click33 commented Jan 2, 2023

也不是完全没效果,是只清除 Session 数据,token 需要你在前端手动清理

@ddxl123
Copy link
Author

ddxl123 commented Jan 2, 2023

@click33
好的,明白了,谢谢。
就是我想实现的业务是,如果是token无状态模式,后端就没法操作指定客户注销下线。
但是把token存入redis,校验的时候,只需要判断redis中token是否存在,即可判断用户是否注销,这样子就可以在服务端针对指定客户进行注销操作了。
但是混入模式使用起来,感觉就和StpLogicJwtForStateless区别不大了,都是前端手动注销。

http://pointborn.com/article/2020/10/9/1003.html

希望增加 token redis 白名单功能。

@click33
Copy link
Collaborator

click33 commented Jan 2, 2023

你说的就是第一种模式:Simple 模式
既把数据存 jwt 令牌中,也往 redis 中存一份

@ddxl123
Copy link
Author

ddxl123 commented Jan 2, 2023

你说的就是第一种模式:Simple 模式 既把数据存 jwt 令牌中,也往 redis 中存一份

啊,我还以为 simple 模式只是用jwt来产生token仅此而已,以为会和不引入jwt效果一样,就一直没关注过simple模式。
对不起,我刚开始的时候就考虑偏差了。。。

@ddxl123 ddxl123 closed this as completed Jan 2, 2023
@dejavuhuh
Copy link

也不是完全没效果,是只清除 Session 数据,token 需要你在前端手动清理

@click33 但是我看logout方法里面也没有清除Session呀,调用完logout之后,再调用isLogin()仍然返回true,这不合理吧?
image

@dejavuhuh
Copy link

@click33 目前在Mixin模式下,必须这样写才能完全登出:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants