服务端一般怎么处理 token? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lightzh
V2EX    程序员

服务端一般怎么处理 token?

  •  
  •   lightzh 2017 年 4 月 1 日 12215 次点击
    这是一个创建于 3267 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前一直在写 iOS ,前后端分离,每次请求带上 token 就行了。

    现在想写一下后端,想问一下一般是怎么处理 token 的?

    用户登录的时候根据 userID 加上时间戳 或者 加上一个自定义值 用加密算法生成 token 之后,

    1.存到数据库中(能设置过期时间吗?),每次客户端请求的时候取出来验证

    2.存到 redis 中,设置过期时间,每次客户端请求的时候取出来验证

    3.不存,每次客户端请求的时候根据之前的生成方法再生成一次来验证

    哪种方法成本更低? 或者有更好的方法吗?

    第 1 条附言    2017 年 4 月 1 日
    感觉大家的回复。

    和一些后台程序员也讨论了一下,很多都是不存,即用 JWT

    https://jwt.io/

    目前已经有很多语言的库都支持了。
    38 条回复    2017-04-02 13:23:41 +08:00
    sfwn
        1
    sfwn  
       2017 年 4 月 1 日
    第三种能解释下吗
    chuanwu
        2
    chuanwu  
       2017 年 4 月 1 日
    @sfwn 猜测应该是类似 jwt 那种吧。
    lightzh
        3
    lightzh  
    OP
       2017 年 4 月 1 日
    @sfwn
    例如客户端登录后服务器生成 token 之后返回,之后客户端请求的时候带上这个 token ,服务端每次都根据之前生成的方法(例如加上了自定义值,使用了什么加密算法)再生成一次来比较,一样就验证成功
    就是楼上说的 JWT ,我也是刚接触
    horsley
        4
    horsley  
       2017 年 4 月 1 日
    我实现过的是不存,仅验证
    lurenw
        5
    lurenw  
       2017 年 4 月 1 日
    有的数据库是支持设置过期时间的, 1 和 2 一个意思。
    ytmsdy
        6
    ytmsdy  
       2017 年 4 月 1 日
    一般都是 token+用户名,在数据库中查询 token 对应的用户名。
    如果用户名和客户端发送的一致则继续正常的访问。
    如果不一致丢 401 错误。
    jedrek
        7
    jedrek  
       2017 年 4 月 1 日   1
    都不需要存,对用户 ID 和过期时间戳签名即可得到 token 。
    token 不应存私密的信息,所以不需要加密。而是要签名,防篡改。
    klesh
        8
    klesh  
       2017 年 4 月 1 日 via Android   1
    看 jwt 规范你就明白了。
    一般不需要存,但若要实现 revoke 之类就要存储
    jedrek
        9
    jedrek  
       2017 年 4 月 1 日   1
    @klesh 比如修改密码后,需要吊销之前的 token ,所以用户 ID 和过期时间戳之外,再加一个值,这个值可存在缓存中,每次请求先对 token 验证,通过后再拿缓存中的值与 token 中的比较
    byfar
        10
    byfar  
       2017 年 4 月 1 日
    登录成功后生成一个 token 存表存 redis 都行

    一个 token 对应一个 uid
    avichen
        11
    avichen  
       2017 年 4 月 1 日
    JWT : Json web Token ,可以去了解一下
    klesh
        12
    klesh  
       2017 年 4 月 1 日   1
    @jedrek

    这样的流程需要进行, 1 。解码 token , 2 。验证 token , 3 。把值与缓存比对。
    我认为不需要所谓的“值”,直接把 token 放到缓存中,利用 set 进行比对是很快的,都不需要解码和验证 token 。同时, token 一定要设定有效期,如一周,这样缓存中只需存最近一周内被 revoke 的 token ,在空间和时间上更合理。如果用户不喜欢每七天登录一次,可以在客户端设计一套自动 refresh token 的机制。
    Ouyangan
        13
    Ouyangan  
       2017 年 4 月 1 日
    直接用 session 吧 ,自己搞来搞去最后都搞成了 session
    sampeng
        14
    sampeng  
       2017 年 4 月 1 日
    一直很不理解 token 的使用场景。。。搞来搞去不就是个 session 么?
    完整实现了 http 协议的哪个不能支持 session ?还是因为懒
    SourceMan
        15
    SourceMan  
       2017 年 4 月 1 日
    2
    jimzhong
        16
    jimzhong  
       2017 年 4 月 1 日
    @sampeng 主要是因为 session 依赖于 cookie 吧
    jedrek
        17
    jedrek  
       2017 年 4 月 1 日   1
    不用 JWT , token 是这样的结构:签名后的字符串-用户 ID-指纹,共三段,每段中划线分隔.由于要谈到 token 吊销需要存储的问题,所以这里可以不需要存时间戳了。

    当注册 /登录成功后:
    1. 指定一个指纹,任意值都可以,只要这个值对这个用户没有使用过即可。
    2. 将指纹和用户 ID 拼起来并签名,组成 签名后的字符串-用户 ID-指纹 这样结构的 token 。
    3. 将用户 ID 与指纹对应起来放到缓存中,并且设置缓存过期时间,这个时间就是 token 有效期。
    4. 将 token 返回给客户端。

    当用户再次请求时:
    1. 将 token 中的用户 ID 和指纹再签名(通过服务端私钥),比对提交的 token 签名后的字符串 就可将篡改或伪造的 token 过滤掉了(或许这一步有更好的实现方式)。
    2. 过了上一步,仍然无法确定 token 是否已被吊销。获取缓存中的指纹与提交的 token 的指纹比对,若缓存中取不到指纹值(缓存已设置过有效期期)或缓存中的指纹与 token 的指纹值不相符,就说明这个 token 被吊销了。
    3. 通过了上面两步,表示这个请求是已认证了的。
    jedrek
    &nbp;   18
    jedrek  
       2017 年 4 月 1 日
    @klesh 忘了
    jarlyyn
        19
    jarlyyn  
       2017 年 4 月 1 日
    我是做了一个 cachegroup.
    前端 redis 热数据,后端 mysql 全部数据。

    另外, token 不是应该随机生成的吗?
    ppmoon
        20
    ppmoon  
       2017 年 4 月 1 日   1
    推荐楼上说的 JWT ,这种方式比较简单,如果应用安全级别不高很实用。客户端存一份 token ,存哪里都行,然后每次需要权限操作的时候就带着 token 去请求。后端接到请求的时候就验证一下。 JWT 把状态放在客户端,后台压力小,要是使用 session 还需要占用服务器资源。 session 多了还需要去管理 session
    jarlyyn
        21
    jarlyyn  
       2017 年 4 月 1 日
    @sampeng

    Session 一般(除了 cookie based session )就是基于 token 的一种具体实现啊。

    不就是把 token 存在对应的 cookie 里么……
    kulove
        22
    kulove  
       2017 年 4 月 1 日
    aes 加密用户 id ,过期时间 每次请求解密判断是否过期
    phx13ye
        23
    phx13ye  
       2017 年 4 月 1 日
    如果 jwt 也要存,不就变成 session 了么,后续又会遇到一对分布式 session 要处理的问题,这样好处在哪?求详细说明
    avichen
        24
    avichen  
       2017 年 4 月 1 日
    @phx13ye #23 jwt 在 local 本地存储,每次请求带过去,让 server 校验,不会存在分布式的问题
    phx13ye
        25
    phx13ye  
       2017 年 4 月 1 日
    @avichen 想把 JWT 作为 app 端和网页端登录凭证。那么 logout 的时候,一般也只是客户端删掉 JWT吗?

    假如在 payload 里设置过期时间 60 秒,如何防止在 59 秒还可以成功请求, 61 秒就要求用户重新登录的情况呢? JWT 有自带的机制去处理吗
    vjnjc
        26
    vjnjc  
       2017 年 4 月 1 日
    1 , 2 看起来一样。 1 的话存的时候带过期时间呀。
    3 的话看起来不安全,通过逻辑生成总是有漏洞(/规律)
    avichen
        27
    avichen  
       2017 年 4 月 1 日   1
    @phx13ye #25 logout 时可以采用你说的删除 token ,另外 59 秒的问题,貌似没有解决办法,这一秒请求完了,下一秒再请求,它不就过期了嘛,对你的业务影响会很大吗?
    behappy
        28
    behappy  
       2017 年 4 月 1 日
    @jarlyyn
    请教一个问题,假如我先打开网页 A ,这时候服务器在努力运算生成 token,但是出于某种原因卡住了。然后我又开了个新标签仍然打开网页 A, 然而这次服务端生成 token 后很快就返回了然后写入 cookie 成功了。然后前一次的 token 慢悠悠的返回了,把第二次的 token 覆盖掉了。这种情况该咋整
    Ouyangan
        29
    Ouyangan  
       2017 年 4 月 1 日
    @behappy jwt 的话没有影响 , token 合法就成了 , 因为服务器根本就没存 token.
    jarlyyn
        30
    jarlyyn  
       2017 年 4 月 1 日
    @behappy

    你的 token 是存在 cookie 的吗?

    这是标准的 session 啊。

    应该是最后一个 token 生效。
    CareiOS
        31
    CareiOS  
       2017 年 4 月 1 日
    @sfwn 就是服务器用对称加密,将数据加密得到一个 string ,然后返回给 client, 每次 client 请求都带上这个 string, 服务器收到后解密,判断是否过期等....
    asen477
        32
    asen477  
       2017 年 4 月 1 日
    一般 app 端存 token 不会做短期的时间验证
    一般存在本地都会很长时间。
    behappy
        33
    behappy  
       2017 年 4 月 1 日
    @jarlyyn 好的
    chuanwu
        34
    chuanwu  
       2017 年 4 月 1 日
    @phx13ye 对于这种场景, jwt 确实没有好的方式解决,这时候可以依赖服务端来做啊。
    phx13ye
        35
    phx13ye  
       2017 年 4 月 1 日 via iPhone
    @avichen 想知道有没有最佳实践
    phx13ye
        36
    phx13ye  
       2017 年 4 月 1 日 via iPhone
    @chuanwu 嗯,之前的做法是在记录一下心跳时间,导致服务端要记录。也许可以在快要过期时重新分配一个 token 更好
    yankbytes
        37
    yankbytes  
       2017 年 4 月 2 日 via iPhone
    @behappy 再去拿个 token ?一般来说除了 accesstoken 还会有 refreshtoken
    sutra
        38
    sutra  
       2017 年 4 月 2 日
    spring-session
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3457 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 12:56 PVG 20:56 LAX 05:56 JFK 08:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86