ParcelS实现单点登录
一、业务场景
场景一:用户1(非IT)使用账号A登录系统后,用户2(非IT)再登录账号A,则会将用户1登录的账号踢下线,系统并弹窗提示;
场景二:用户1(非IT)使用账号A登录系统后,用户2(IT)再登录账号A,不会将用户1踢下线;
场景三:用户1(IT)使用账号A登录系统后,用户2(非IT)再登录账号A,不会将用户1踢下线;
场景四:用户1(IT)使用账号A登录系统后,用户2(IT)再登录账号A,不会将用户1踢下线。
二、解决方案
方案1:在旧的session设置值,isLogin方法中获取当前登录session是否有设置过属性值,有则退出当前账号。
实现步骤:
- 登录时,通过获取redis中是否有记录过该用户的sessionId判断账号是否已经被登录过;
- 如果当前账号已经登录,则获取旧的session,并设置属性标记(如:“keckout”, ture);
- 系统调用isLogin接口时,获取当前登录的session,查看是否有设置过属性标记,有则将当前登录的账号踢下线。
业务流程:
优点:简单直接,主要针对session做事情
缺点:未找到比较好的方法来获取旧的session
方案2:登录时如果发现账号已被登录,直接删除该session
实现步骤:
- 登录时,通过获取redis中是否有记录过该用户的sessionId判断账号是否已经被登录过;
- 如果当前账号已经登录,直接将对应的session删掉;
- 系统调用isLogin接口时,当检测到session没有了则直接退出。
业务流程:
缺点:当被踢出时候无法在页面返回正确的消息提示(为何掉线了?)
方案3:将上一次登录的sessionId存到redis中
实现步骤:
- 登录时,通过获取redis中是否有记录过该用户的sessionId判断账号是否已经被登录过;
- 如果当前账号已经登录,把登录过的sessionId存入到redis中;
- 系统调用isLogin接口时,获取当前登录的sessionId,并且从redis中取当前user的sessionId,如果不一致,则将其踢出。
业务流程:
缺点:并发登录时候由于只记住了最后一次的sessionId,所以不能将已登录的完全踢出去
方案4:只要不是最后登录sessionId的,都自动退出
实现步骤:
- 登录时,通过获取redis中是否有记录过该用户的sessionId判断账号是否已经被登录过;
- 如果当前账号已经登录,把当前登录的sessionId存入到redis;
- 系统调用isLogin接口时,当检测到当前登录用户的sessionId不等于redis中存的userId对应的sessionId时则直接退出。