限制单用户多地登录
2018-03-13 本文已影响16人
单调先生
Nodejs的做法
在上一篇文章Nodejs中的JWT和Session中,我最后采用了session的形式做用户识别与授权,根据业务要求,系统需要单点登录功能,描述如下
单点登录:限制同一帐号同一时刻只能一个用户登录使用,像QQ一样
一开始接到这个需求的时候在想应该如何来做,上网查找关键字单点登录,发现搜索到的并不是需求中描述的单点登录(怀疑需求中的单点登录并不是叫单点登录),最后换了一些关键词才找到如何实现的,参照这篇博客1以及博客2我做了如下一些整理
- 实现在线列表
- 用户异地登录后上一登录状态失效
-
用户正常退出或关闭浏览器(标签页)登录状态失效
单点登录流程
实现在线列表这里我采用redis来存储登录状态,3的部分session的机制已经帮我们解决了这个问题,具体的代码实现如下
//额外引入redis && connect-redis
npm i redis && connect-redis --save
//node
const cookieParser = require('cookie-parser');
const session = require('express-session');
const redis = require('redis');
const redisStore = require('connect-redis')(session);
const redisClient = redis.createClient({
host: 'localhost',
port: 6379
})
const store = new redisStore({
client: redisClient,
logErrors: true
})
app.use(cookieParser(config.secret));
app.use(session({
secret: ‘justyoulike’,
resave: true,
saveUninitialized: false,
rolling: true,
store: store,
genid: req => {
//生成唯一ID作为reids存储的key值
//key = username + '/' + random
let username = req.body.username;
return `${username}/${parseInt(Math.random() * 1000)}`
},
cookie: {
maxAge: config.maxAge
}
}))
//在login的逻辑中插入如下代码片段
redis.keys(`sess:${username}/*`, (err, reply) => {
if (! err && reply.length > 0) {
//这一步可以确保用户异地登录后上一登录状态失效
redis.del(reply[0]);
}
})
Java的做法
如果你的项目里采用了Spring Security,那么使用以下配置可以很方便的达成目的。当然,也可以选择重写它的内部类
//web.xml
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
//应用程序部分,如我的项目中的applicationContext-security.xml
<http>
<session-management>
<!-- max-sessions可以设置同一时刻单用户可以运行多少个在线数 -->
<concurrency-control max-sessions="1"/>
</session-management>
</http>