V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liangtao927190
V2EX  ›  Node.js

关于单用户登录的设计求教!使用 koa2+mysql

  •  
  •   liangtao927190 · 2019-01-14 16:17:25 +08:00 · 5247 次点击
    这是一个创建于 2119 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有个小项目,而且目前只进行到 demo 阶段,目前是用 koa2+jwt 来鉴权,但是遇到一个问题,需要做单用户登录。意思就是 A 用户用账号密码登录了以后,别人再用 A 的账号密码登录,要么提示该账号已在线,要么在线的 A 就无法继续使用。
    现在想不好怎么做,是维护一个用户在线表,登录以后保存在表里,后面请求都要保证用户 id 不在表里存在才给使用?还是有别的办法?

    求大神帮助。
    16 条回复    2019-01-24 16:22:09 +08:00
    bestie
        1
    bestie  
       2019-01-14 16:21:12 +08:00
    redis ?
    raphael008
        2
    raphael008  
       2019-01-14 16:25:53 +08:00
    user + jwt 存 redis,薄见,有请楼下高人解答👇
    liangtao927190
        3
    liangtao927190  
    OP
       2019-01-14 16:36:26 +08:00
    可否稍微具体一点?是我说的思路的吗?就把 user 存 redis 里,后面的登录请求就必须先检查是否存在?
    我主要是做前端的,后台的东西稍微有一点基础但不是很了解。望大家指点
    谢谢了
    zhichaozhang
        4
    zhichaozhang  
       2019-01-14 16:41:15 +08:00 via iPhone
    @liangtao927190 那就存在 mysql 中 问题不大
    ooh
        5
    ooh  
       2019-01-14 17:16:57 +08:00
    实现一个 signout 方法不就可以了吗
    lovedebug
        6
    lovedebug  
       2019-01-14 17:20:42 +08:00   ❤️ 1
    可以考虑用 redis,存 userid:1,value 为次数,设置自动过期时间,每次登陆都加锁 query
    GTim
        7
    GTim  
       2019-01-14 17:27:34 +08:00   ❤️ 2
    严格意义上来说:

    1. jwt 的密钥不同,那么之前登录的就会自动失效
    2. jwt 的密钥的唯一作用,是鉴定 token 是否合法
    3. jwt 的机制本身,并无法判定之前是否有登录

    建议密钥的生成方式为:登录时的时间戳 + 固定后缀


    做法很简单,就是每次登录改动密钥。


    1. 假设你已经有了 visited_at 字段用于表示用户最后访问时间,且有一个字段 lasted_at 用于表示最后登录时间(用于登录密钥)

    2. jwt 的机制,每次访问都必须带上 token。 每次访问的时候更新用户最后访问时间,否则设定一个时间,比如 30 分钟后登录过期

    3. jwt 登录判定:如果 visited_at 存在且小于 30 分钟,则表示有用户存在,否则表示没有登录用户。
    zohan
        8
    zohan  
       2019-01-14 17:43:11 +08:00
    单点登录。楼上已经给了一套方案啦
    keepeye
        9
    keepeye  
       2019-01-14 17:45:02 +08:00
    redis 存 session
    gz911122
        10
    gz911122  
       2019-01-14 18:37:15 +08:00
    7l 是正确做法
    别的存 redis 的能用,但是违背了 jwt 的本意
    xuanbg
        11
    xuanbg  
       2019-01-15 07:19:45 +08:00
    JWT 应该是不支持这个功能的,所以你只能把 JWT 再包一层,自己去管理用户状态。
    zgcwkj
        12
    zgcwkj  
       2019-01-15 11:41:58 +08:00
    liangtao927190
        13
    liangtao927190  
    OP
       2019-01-15 15:12:37 +08:00
    @GTim 请问假如同一个用户未注销的情况下再次登录该怎么办?这个逻辑上来看岂不是也会判断成已有人登录了?
    因为是用在微信小程序里,如果用户把小程序关掉了再次打开,理论上来说我还是会再调用一次登录的
    GTim
        14
    GTim  
       2019-01-15 16:21:28 +08:00
    在小程序你不是要保存用户的 token 么? 如果这时候调用小程序再次登录,你仍然可以把 token 传上去

    如果用户未注销,那么就意味着密钥没有被替换是不? 那原先的 token 可以校验通过啊,这相当于用户没有退出,只是好久不访问而已
    liangtao927190
        15
    liangtao927190  
    OP
       2019-01-15 18:04:24 +08:00
    @GTim 懂了。持久保存 token 而不是随着微信关闭而关闭
    x1911
        16
    x1911  
       2019-01-24 16:22:09 +08:00
    redis 存 token,带上过期时间,新用户登录时搜搜 redis,能搜到就说明在登录中

    这时你想禁止新人还是踢掉旧人都可以了,

    没登录的就没有 token,或者 token 过期,

    这样原本登录过的人只要 token 不变就是一直登录状态
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2747 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:44 · PVG 22:44 · LAX 07:44 · JFK 10:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.