V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drymonfidelia
V2EX  ›  程序员

要做实时登出的客户端 API,是不是完全不适合 JWT 鉴权?每个请求都要验证 token 有效性,传输和验证签名看起来是在浪费资源

  •  
  •   drymonfidelia · 30 天前 · 2471 次点击
    第 1 条附言  ·  30 天前
    我想到一种场景是 JWT 携带用户名、权限列表,这样客户端能直接解析展示,一个 tokenID 用来区分这个 JWT ,请求的时候服务检查完 JWT 后 gRPC 调用鉴权服务查 tokenID 是否被登出,如果没登出,直接用 JWT 里携带的权限列表,同时缓存 tokenID 有效信息 10 秒。但是这有意义吗,用户名、权限列表可以单独返回给客户端保存,调用鉴权服务查 tokenID 的时候可以直接从 redis 里读这些信息。明显省一点带宽改善弱网环境体验比省这一点服务器内存空间和服务器间带宽有意义得多
    25 条回复    2024-11-05 18:31:31 +08:00
    IvanLi127
        1
    IvanLi127  
       30 天前
    我觉得只跑一个实例单体应用都不适合。其他情况或许有适合的用例。
    要用 jwt 实现的话,做 token 黑名单查也能做出实时的效果。
    renmu
        2
    renmu  
       30 天前 via Android
    不合适
    crysislinux
        3
    crysislinux  
       30 天前 via Android
    登录还是 session 做吧。
    CodeY99
        4
    CodeY99  
       30 天前
    感觉除非分布式要求非常高,无数台机子要分布式验证,真心不如 session
    excxapp
        5
    excxapp  
       30 天前
    JWT 有个办法,就是针对 token 增加时间戳,每次删除后,更新最新的时间戳,然后存到 redis 里面,比较时间戳之后的即可
    zhenjiachen
        6
    zhenjiachen  
       30 天前 via iPhone
    @excxapp 这不就是 session 吗?这样有啥意义,用着 jwt 但是自己造了个 session ?
    Belmode
        7
    Belmode  
       30 天前 via Android
    想法很好,设计是可行的。不过有点需要注意,如果权限数据很多,不建议直接放到 jwt 里。
    excxapp
        8
    excxapp  
       30 天前
    @zhenjiachen jwt 的优势加个个性化需求了呗,楼主就是要登出,不然咋实现叻
    dreamk
        9
    dreamk  
       30 天前
    jwt 是无状态的,踢人不适合 jwt ,用黑名单反而复杂了
    dreamk
        10
    dreamk  
       30 天前
    grpc 可以用 basic auth 加盐的密码,放到 metadata ,类似于 http1 rest 请求的请求头
    wxf666
        11
    wxf666  
       30 天前 via Android
    @excxapp 如果每个请求,都要去 redis 判断一下,是否登出了,

    为何不把 JWT 里的内容,挪到 redis 里,拿不到就是登出呢?

    这样,每个网络请求能更小,带宽需求更低呀?
    dreamk
        12
    dreamk  
       30 天前
    @wxf666 jwt 就是存客户端的,还存服务器 redis 不多此一举吗。重启下服务集体登出?
    wxf666
        13
    wxf666  
       30 天前
    @dreamk #12

    挪到,不是双重存储。。否则挪用公款,就是变出两份钱财的意思吗。。

    redis 不是有 AOF 、RDB 机制吗?重启也不会丢数据呀。。
    fox0001
        14
    fox0001  
       30 天前 via Android
    @wxf666 #11 放到 redis 的话,就是 session 了
    bluearc
        15
    bluearc  
       30 天前
    可以,在下发 jwt 前先存储 tokenid ,用户登出后销毁 tokenid,不过这样事实上也就变成 session 了,如果 tokenid 过期时间长的话可以用黑名单,时间短的话还是仅记录每个用户最新的 tokenid
    qsnow6
        16
    qsnow6  
       30 天前   ❤️ 1
    jwt 主要是用于资源鉴权使用的,登录状态的保留最佳实践就是 session 。我司 PHP 就是把 jwt 当 session 使用,导致服务器要踢用户下线时(改密码、修改权限)非常麻烦。
    amlee
        17
    amlee  
       30 天前
    jwt 的设计理念就是无状态呀,你这“登出”的功能本身就是有状态的设计。
    如果强行使用 jwt 来做登录、登出,那么必然后台要维护一个 jwt 的黑名单,这就又把状态引入回来了

    直接用 session 就好了
    iseki
        18
    iseki  
       30 天前 via Android
    即使这样我觉得用 JWT 也不是不行:
    1. JWT 有标准化的规格说明,IETF RFC ;
    2. 没必要为了节省传递 token 的那点流量把自己的路堵死,日后万一需要无状态降级也有机会;
    vishun
        19
    vishun  
       29 天前
    jwt 压根不适合普通的用户登录,应用场景也非常有限,像是 ruoyi 系统这种用 jwt 作为普通 token ,只增加了解析复杂度和 token 长度这些缺点,换成随机字符串要好很多。
    lairdnote
        20
    lairdnote  
       29 天前
    有 refresh 时间短点就搞定啊
    xuanbg
        21
    xuanbg  
       29 天前
    你这个就别用什么 JWT 了,一个 sessionId 发给用户,然后后端根据这个 id 来读取用户权限进行鉴权就好了。把一堆的授权信息放在 JWT 里面,纯纯的浪费流量
    xuanbg
        22
    xuanbg  
       29 天前
    @iseki 你这个说法没有任何道理。对于前端来说,请求头放 JWT 还是 sessionId 没有任何区别,反正多了拿到什么就放什么。所以以后改成 JWT 也好,其他的什么也罢,都只要改后端登录和身份验证、鉴权逻辑就行了,用什么就改什么,和前端半毛钱关系都没有。
    iseki
        23
    iseki  
       29 天前 via Android
    @xuanbg 我何时说跟前端有关系了?
    xuanbg
        24
    xuanbg  
       29 天前
    @iseki 我只是说想改随时能改啊,不存在你说的把自己的路堵死的情况
    iseki
        25
    iseki  
       12 小时 53 分钟前
    @xuanbg

    1. 已经发出去的 token 怎么办
    2. 改动内容多半比开始就用 JWT 要大
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1234 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:24 · PVG 07:24 · LAX 15:24 · JFK 18:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.