vue相关知识程序员

限制单用户多地登录

2018-03-13  本文已影响16人  单调先生

Nodejs的做法

在上一篇文章Nodejs中的JWT和Session中,我最后采用了session的形式做用户识别与授权,根据业务要求,系统需要单点登录功能,描述如下

单点登录:限制同一帐号同一时刻只能一个用户登录使用,像QQ一样

一开始接到这个需求的时候在想应该如何来做,上网查找关键字单点登录,发现搜索到的并不是需求中描述的单点登录(怀疑需求中的单点登录并不是叫单点登录),最后换了一些关键词才找到如何实现的,参照这篇博客1以及博客2我做了如下一些整理

  1. 实现在线列表
  2. 用户异地登录后上一登录状态失效
  3. 用户正常退出或关闭浏览器(标签页)登录状态失效
    单点登录流程
    实现在线列表这里我采用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>
上一篇下一篇

猜你喜欢

热点阅读