Nodejs 关于单用户登录的设计求教 使用 koa2+mysql
Nodejs 关于单用户登录的设计求教 使用 koa2+mysql
有个小项目,而且目前只进行到 demo 阶段,目前是用 koa2+jwt 来鉴权,但是遇到一个问题,需要做单用户登录。意思就是 A 用户用账号密码登录了以后,别人再用 A 的账号密码登录,要么提示该账号已在线,要么在线的 A 就无法继续使用。
现在想不好怎么做,是维护一个用户在线表,登录以后保存在表里,后面请求都要保证用户 id 不在表里存在才给使用?还是有别的办法?
求大神帮助。
redis ?
可否稍微具体一点?是我说的思路的吗?就把 user 存 redis 里,后面的登录请求就必须先检查是否存在?
我主要是做前端的,后台的东西稍微有一点基础但不是很了解。望大家指点
谢谢了
那就存在 mysql 中 问题不大
实现一个 signout 方法不就可以了吗
可以考虑用 redis,存 userid:1,value 为次数,设置自动过期时间,每次登陆都加锁 query
严格意义上来说:
1. jwt 的密钥不同,那么之前登录的就会自动失效
2. jwt 的密钥的唯一作用,是鉴定 token 是否合法
3. jwt 的机制本身,并无法判定之前是否有登录
建议密钥的生成方式为:登录时的时间戳 + 固定后缀
做法很简单,就是每次登录改动密钥。
1. 假设你已经有了 visited_at 字段用于表示用户最后访问时间,且有一个字段 lasted_at 用于表示最后登录时间(用于登录密钥)
2. jwt 的机制,每次访问都必须带上 token。 每次访问的时候更新用户最后访问时间,否则设定一个时间,比如 30 分钟后登录过期
3. jwt 登录判定:如果 visited_at 存在且小于 30 分钟,则表示有用户存在,否则表示没有登录用户。
单点登录。楼上已经给了一套方案啦
redis 存 session
7l 是正确做法
别的存 redis 的能用,但是违背了 jwt 的本意
JWT 应该是不支持这个功能的,所以你只能把 JWT 再包一层,自己去管理用户状态。
请问假如同一个用户未注销的情况下再次登录该怎么办?这个逻辑上来看岂不是也会判断成已有人登录了?
因为是用在微信小程序里,如果用户把小程序关掉了再次打开,理论上来说我还是会再调用一次登录的
在小程序你不是要保存用户的 token 么? 如果这时候调用小程序再次登录,你仍然可以把 token 传上去
如果用户未注销,那么就意味着密钥没有被替换是不? 那原先的 token 可以校验通过啊,这相当于用户没有退出,只是好久不访问而已
懂了。持久保存 token 而不是随着微信关闭而关闭
redis 存 token,带上过期时间,新用户登录时搜搜 redis,能搜到就说明在登录中
这时你想禁止新人还是踢掉旧人都可以了,
没登录的就没有 token,或者 token 过期,
这样原本登录过的人只要 token 不变就是一直登录状态
在Node.js中,使用Koa2和MySQL实现单用户登录(SSO)的设计,可以通过以下步骤实现。这里简要描述流程并提供部分代码示例。
-
用户注册/登录:用户注册时,将用户名和密码(哈希处理)存入MySQL数据库。登录时,验证用户名和密码。
-
会话管理:使用Koa的session中间件来管理用户会话。
以下是一个简单的实现思路:
安装依赖
npm install koa koa-router koa-session2 mysql2 bcryptjs
数据库连接(db.js)
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
module.exports = pool.promise();
路由实现(app.js)
const Koa = require('koa');
const Router = require('koa-router');
const session = require('koa-session2');
const db = require('./db');
const bcrypt = require('bcryptjs');
const app = new Koa();
const router = new Router();
app.keys = ['your-session-secret'];
app.use(session(app));
// 注册、登录逻辑省略,需查询数据库并处理密码哈希
router.get('/login', async (ctx) => {
// 检查ctx.session.user,若存在则已登录
ctx.body = 'Login page';
});
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000, () => console.log('Server running on port 3000'));
此示例仅包含基础框架,实际开发中需处理更多细节,如密码哈希、错误处理、用户注销等。