V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
guyskk
V2EX  ›  Python

Token 过期的问题

  •  
  •   guyskk ·
    guyskk · 2016-09-13 19:35:54 +08:00 · 33353 次点击
    这是一个创建于 2994 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前流程是用户登录成功之后,返回一个 token 给客户端, token 过期时间为 30 分钟。请求其他 API 时客户端带上 token ,服务端依据此 token 判断是否登录。 现在问题是 token 会过期,过一段时间就要重新登录,把过期时间设长一点只能减少过期的频率,不能根本上解决问题。 所以有没有像 Session 那样,只要用户一直在线就不过期,超过一定时间不在线才会过期的库 /算法 /Demo ?

    https://github.com/mattupstate/flask-jwt/isues/29
    refresh token 也看了一些,感觉有点复杂

    第 1 条附言  ·  2016-09-13 21:23:21 +08:00
    22 条回复    2016-09-15 12:09:46 +08:00
    virusdefender
        1
    virusdefender  
       2016-09-13 20:25:55 +08:00 via iPhone
    心跳包,每次增加一段时间的有效期
    Sharuru
        2
    Sharuru  
       2016-09-13 20:28:54 +08:00 via Android
    session 也是有过期时间的。

    很简单的做法就是每次使用 token 前(你总有个方法检测 token 是否有效吧?),顺手延长一下 token 的有效期。
    bk201
        3
    bk201  
       2016-09-13 20:35:58 +08:00 via iPhone   ❤️ 1
    快要过期发数据包续命
    laoyur
        4
    laoyur  
       2016-09-13 20:39:18 +08:00
    这个问题我也想过
    似乎正面的方案就是用 refresh_token 机制,这个就是费客户端一点事而已,如果实在觉得烦
    可不可以服务端自己写一个 middleware ,判断 token 快要失效时,主动颁发一个新的 token 给客户端,当然,这还是需要客户端来配合,依然烦躁……
    morewe
        5
    morewe  
       2016-09-13 20:49:12 +08:00
    每次 APP 启动登录的时候给 token 续命。
    uniquecolesmith
        6
    uniquecolesmith  
       2016-09-13 20:54:28 +08:00
    jwt 解决你需求 如果你的 jwt 是有效的,只要每次更新 jwt 即可 同时 jwt 也有过过期时间 所以完全满足你 (如果不知道 搜一下)
    uniquecolesmith
        7
    uniquecolesmith  
       2016-09-13 20:57:27 +08:00
    关于楼上 @laoyur 说的 之前也试过(之前微信公众号的接口也有这个属性 但是后来取消了) 但是效果不不好 一般也用不到
    DRcoding
        8
    DRcoding  
       2016-09-13 21:03:42 +08:00
    微信公众号的 token 是需要一个中控服务器定时请求刷新的,有效期两小时。
    登录后,客户端也可以定时像服务端接口请求一个新的访问的 token 。
    Totato5749
        9
    Totato5749  
       2016-09-13 21:10:05 +08:00   ❤️ 1
    之前公司项目也有这问题,是在是烦躁,于是就改成很简单的,每次用到 token 的接口服务器直接给这个 token 续期。。。 也就是说如果用户一段时间没用 app , token 才会过期
    uniquecolesmith
        10
    uniquecolesmith  
       2016-09-13 21:11:51 +08:00   ❤️ 1
    仔细看 发现 LZ 也用了 jwt, jwt 很简单 是过去 token 的升级版 非常强大
    guyskk
        11
    guyskk  
    OP
       2016-09-13 21:16:16 +08:00 via Android
    @uniquecolesmith
    用 jwt 应该是可行的,但是看那个 issue 一直没解决,我感觉是更新 jwt 的算法卡住了,如果每次请求都更新一下 token ,会不会太频繁了。
    laoyur
        12
    laoyur  
       2016-09-13 21:23:01 +08:00   ❤️ 1
    @guyskk 所以用我说的『可不可以服务端自己写一个 middleware ,判断 token 快要失效时,主动颁发一个新的 token 给客户端』这种方案开销会较小
    你一个请求发到服务端,服务端是知道这个 token (当然是用 jwt 了,服务端不用额外来维护已经颁发出去的 token )啥时候过期的,如果发现快要过期了,就主动颁发一个新的 token 过去
    这种方案的话客户端逻辑最简单,就不需要主动去调用 refresh_token 接口了,不过还是需要客户端在 response 的地方统一处理一下新颁发的 token
    vghdjgh
        13
    vghdjgh  
       2016-09-13 21:28:00 +08:00   ❤️ 1
    安全的 session 是不能无限被刷新的,所以肯定有最终过期时间,可以设置为 token 的过期时间,这样就避免刷新 token 了。
    一般移动端的过期时间以月为单位, web 端一般以天为单位。
    vghdjgh
        14
    vghdjgh  
       2016-09-13 21:29:39 +08:00
    web 端自动登录的以周为单位。
    这样性能也很好的,不会频繁产生 token 。
    guyskk
        15
    guyskk  
    OP
       2016-09-13 21:38:05 +08:00 via Android
    @vghdjgh
    如果登录后返回一个过期时间为 1 周的 token ,一周后 token 即将过期的那段时间,如果用户正在浏览网站,一会 token 过期了,他就需要重新登录,还是会打断正常的使用。
    uniquecolesmith
        16
    uniquecolesmith  
       2016-09-13 21:52:02 +08:00
    首先 相比 IO jwt 计算忽略不计 其次楼上也有人说了 写 middleware 等快过期了再更新即可
    longnight
        17
    longnight  
       2016-09-13 22:05:52 +08:00 via Android   ❤️ 1
    在缓存 /数据库某处保存键值对,纪录{token: last_visited_at}, 然后每次访问时都检查判断 /更新这个时间值,即可。
    说得比较简略,以前做过这样的系统,是可行的
    klesh
        18
    klesh  
       2016-09-13 22:07:16 +08:00   ❤️ 1
    1. 客户端 token 只存简单的数据,如 userId 。永不过期,除非服务端返回 403 状态码。
    2. 当 token 进来时,校验,解析出 userId ,从缓存(如 redis )获得 userData ,若缓存存在,更新过期时间。
    3. 若缓存没有命中,从数据库加载返回同时存入缓存,设置过期时间。
    4. 基于安全考虑,可在 token 中再加入一个 version 字段,在第 2 步时校验该段。当改密码或其它需要将所有已登录的客户端重登时只需更新 version 字段,并清空缓存即可。

    以上,客户端无需主动刷新,也无需定期更换 token ,只有在服务端声明 token 无效时抛弃即可,同时里面也不会包含太多的敏感信息( jwt 只是 base64 编码,随手都可以解析数据出来,不应将敏感数据放在此处),数据量少 token 相对也短些,对传输也有好处;服务端可完全控制 token 的有效性,在必要的情况下可自主 revoke 已颁发的 token 。
    googlebot
        19
    googlebot  
       2016-09-14 04:10:12 +08:00 via Android
    api 的 token 复杂,在 auth 2.0 里,
    普通 auth token 一个小时过期,
    还有一种 fresh token 基本不过期,或半年过期,用 fresh token 可以领新的 auth token ,不用输入密码,
    fresh token 的申请的权限多,
    vghdjgh
        20
    vghdjgh  
       2016-09-14 07:52:31 +08:00
    可以考虑这样一种情况: token3 天过期,然后会刷新 token ,刷新一定次数之后,不能继续刷新了(不然第三方每隔一段时间刷新一下, token 就永不过期了),这时候如果用户正在使用,一样会打断用户的。
    一个方法是,把过期时间加入 token 的公开部分,客户端可以自己解析出过期时间,再通过其它 API 获得服务器时间,就可以知道什么时候过期,可以在客户端定时( 1min )检测,在过期前几分钟,提示“长时间未登录过,为了安全,需要重新登录”。
    vghdjgh
        21
    vghdjgh  
       2016-09-14 07:59:41 +08:00
    也可以稍微延长下时间,例如三周+几个小时,使得会在半夜三点左右过期,这样会减少用户看到提示的概率。
    Comdex
        22
    Comdex  
       2016-09-15 12:09:46 +08:00
    其实不就是每次访问 api 时服务器延长 token 的过期时间就可以了吗?这样的话只有当用户有一段时间没登录时就要求重新登录不也很正常吗? app 可以设置两到三周过期
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5637 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 08:12 · PVG 16:12 · LAX 00:12 · JFK 03:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.