【2022】node实现一个账号同时只能登录一个客户端

本文介绍了如何使用Express和Redis实现一个简单的单设备登录系统。通过生成并存储session ID,以及在接口中进行session ID校验,确保同一账号在同一时间段只能在一个客户端登录。当新的登录尝试发生时,旧的session ID将被清除,从而实现挤线功能。在退出登录时,别忘了销毁session。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

最近自己使用node.js中express框架写了一个小demo,就自己写着玩的。
但是有这样一个需求。
1.同一个账号在同一个时间段只能在一个客户端登录,类似QQ同一个时间段只能在一个手机上登录
2.A客户端先登录,如何在B客户端登录,A客户端就会挤下线。


提示:以下是本篇文章正文内容,下面案例可供参考

一、基本思路

1.使用session在进行登录验证成功后生成sessionID,
2,对除登录接口以外的接口进行sessionID校验,如果sessionID过期或是丢失就返回登录失效

  • 安装所用的包指令
  • npm install express-session session指令
  • npm install redis 用于存储sessionid(也可以用mysql需要安装相关的包)
  • npm install connect-redis (用于连接redis)

二、实现步骤

1.创建连接

1.app.js
const session = require('express-session');
const redis = require('redis');
const redisStore = require('connect-redis')(session);


const redisClient = redis.createClient({
    port: 6379, //端口号
    host: "127.0.0.1" //主机
})

2.储存sessionID

app.use(session({
    secret: 'keyboardcat',
    resave: true,
    saveUninitialized: false,
    store: new redisStore({
        client: redisClient
    }),
    rolling: true,
    genid: req => {
//我这里是进行一个登录接口的判断,就是获取前端传递过来的账号密码,然后我把用户作为sessionid随机数编号存起来
        if (req.url == "/Api/accountLogin") {
            let nickName = JSON.parse(req.body.data);
            return `${nickName.userName}/${parseInt(Math.random() * 1000)}`
        }
    },

    cookie: {
        // 20分钟
        maxAge: 1200000
    },
}))

3.拦截校验

app.use(function (req, res, next) {

    // 对登录接口进行验证
    if (req.url == "/Api/accountLogin") {
    
        let nickName = JSON.parse(req.body.data);
        // 模糊查询当前登录的账号是否在登录
        redisClient.keys(`sess:${nickName.userName}/*`, (err, reply) => {

            console.log("redes模糊查询", reply);
           // 如果存在就清除第一个登录的sessionId
            if (!err && reply.length > 0) {
                redisClient.del(reply[0]);
            }
        })
        next()
    } else {

        // 如果不是登录接口都进行校验sessionid是否有效
        console.log("拦截请求中的sessionid", req.sessionID);

        if (req.sessionID == undefined) {
            // sessionID过期
            res.status(401).send({
                message: '异地登录',
                code: 0
            });
        } else {
            // 不过期继续操作
            next()
        }
    }

});


总结

自己查询了很多资料,参考了博客1博客2自己是现实了这个登录的效果,但是需要注意最后登录退出记得清除会话(session)

 req.session.destroy(err => {
            if (err) {
                res.send({
                    code: 0,
                    message: "退出失败"
                })
            } else {
                res.send({
                    code: 1,
                    message: "退出成功"
                })
            }
        })

希望对你有所帮助,有什么问题可以给我留言,或是私信.在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值