怎么方便全局维护 token, , 有效期二个小时, 快过期的时候主动发请求更新 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
xpyusrs
V2EX    Go 编程语言

怎么方便全局维护 token, , 有效期二个小时, 快过期的时候主动发请求更新

  •  
  •   xpyusrs 2022-06-26 18:22:40 +08:00 4440 次点击
    这是一个创建于 1207 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用什么方案能优雅的实现, 有很多份 token 需要维护, 用定时任务的话, 得设置成千上万个

    29 条回复    2022-06-30 23:50:21 +08:00
    smallthing
        1
    smallthing  
       2022-06-26 18:24:50 +08:00
    什么东西 过期的不是用 refresh token 来申请吗
    吊销的时候删掉 refresh token
    BBCCBB
        2
    BBCCBB  
       2022-06-26 18:27:22 +08:00
    发现过期的时候再去更新行不行?
    xpyusrs
        3
    xpyusrs  
    OP
       2022-06-26 18:28:05 +08:00
    @smallthing 对, 就是快过期的时候用 refresh token 去申请
    xpyusrs
        4
    xpyusrs  
    OP
       2022-06-26 18:28:54 +08:00
    @BBCCBB 这样会有很多无效请求, 想着到期了就更新好
    yangg
        5
    yangg  
       2022-06-26 18:34:51 +08:00 via iPhone
    一个定时任务,每分钟执行,更新这一分钟需要更新的
    BBCCBB
        6
    BBCCBB  
       2022-06-26 18:44:20 +08:00
    但并不是所有的 token 都会使用的吧. 你提前更新无效的请求会更多?
    xpyusrs
        7
    xpyusrs  
    OP
       2022-06-26 18:45:28 +08:00
    @BBCCBB 每个 token 都会用, 用于店铺更新订单
    cpstar
        8
    cpstar  
       2022-06-26 18:50:13 +08:00
    一种方案,独立进程 /线程,独立更新,可以并发或者顺序(主要考虑并行的一致性)
    一种方案,随需随用,过期了则隐含(implicit)更新用例

    either way
    golangLover
        9
    golangLover  
       2022-06-26 18:59:40 +08:00 via Android
    你每次都主动更新,那还用 refresh token 做什么
    AlisaDestiny
        10
    AlisaDestiny  
       2022-06-26 19:06:27 +08:00
    上面说了,时间粗化,精确到分钟,构建一个长度为 120 的循环链表(队列也行),第 i 个节点包含会在 i 分钟过期的 token 列表,每分钟从节点头拿出一个列表更新,然后头指针移动到下一个节点。
    BugCry
        11
    BugCry  
       2022-06-26 19:07:01 +08:00 via Android
    golang 用时间轮就好了
    wangningkai
        12
    wangningkai  
       2022-06-26 20:25:39 +08:00 via iPhone
    可每请求一次更新一次 token 发给客户端更新
    vfs
        13
    vfs  
       2022-06-26 20:44:02 +08:00
    如果是那种过期了也可以很容易刷新的 token , 只需要记录下 token 和对应的 token 过期时间就行。每次使用 token 之前判断一下是否过期,过期了就刷新一下就好。 轮询,按时刷新都太费了,过日子吗,就是要省:-)
    cxytz01
        14
    cxytz01  
       2022-06-26 20:53:33 +08:00
    想到两种解决方法:
    方法一:自己写数据结构 -- 大(小)根堆,优先级队列。
    a.大小根堆存储 token 的时间,每秒扫对顶元素,过期就 pop 出来,继续扫堆顶元素直到再也扫不到过期的,然后进入下一个循环。
    b.优先级队列存储 token 时间,同样每秒扫队顶元素。不过这里貌似都用不着优先级队列,用普通的队列就可以了,毕竟时间都是线性的,顺序的。

    方法二:用工业界的组件 -- 延时消息队列 -- 比如电商领域的订单系统,开单后,N 分钟内不付款,系统就关闭订单。
    haolongsun
        15
    haolongsun  
       2022-06-26 20:53:35 +08:00
    选 lazy 吧,主动轮询检查的是个不明智的选择。全局拦截响应,如果发现 token 过期再用 refresh token 来刷新 token ,再重新请求,就能做到无感刷新 token 。
    cxytz01
        16
    cxytz01  
       2022-06-26 20:56:08 +08:00
    @cxytz01 其中方法一就是定时任务,不过只需要一个定时任务,每 n 秒,或者每 n 分钟扫一次数据结构。你需要自己维护 token 的数据结构。token 应该是存在 DB table 里面的吧,应该都有一个唯一 ID 吧,且有创建时间吧。那么就把这些数据拿出来,搞成大小根堆,或者队列。
    ryanbuu
        17
    ryanbuu  
       2022-06-27 01:41:53 +08:00 via iPhone
    有没有可能中心化呢
    aaniao002
        18
    aaniao002  
       2022-06-27 03:29:56 +08:00 via Android
    数据库+http server+一堆 bash 脚本。bash 脚本运行更新 token ,根据返回 exp 算好到期时间(可提前 10min),sleep 到下个 round 再更新一次。bash 跟新 post 到 http server 然后写入数据库。使用的时候去数据库读取就好。管理能力 3 万起步,用 redis 还能更快。其他群控,docker ,监控,报错提示,管理什么的自由发挥就好。
    SteveWoo
        19
    SteveWoo  
       2022-06-27 03:58:04 +08:00
    生成的 token 就带上时间,每次要用的时候检查是否过期
    SteveWoo
        20
    SteveWoo  
       2022-06-27 04:02:55 +08:00
    哦,上面那条理解错题了。
    我之前遇到同类场景是微信小程序的 authkey 2 小时过期,需要提前更新。解决办法是:

    把生成的 token (或者 wxkey 等及其他可以标记的)放到 redis 的 score set 里,score 就是过期的时间。
    然后启动一个进程每 10 秒扫一下还有 15 分钟就过期的 key ,完成更新操作。
    BeijingBaby
        21
    BeijingBaby  
       2022-06-27 09:51:46 +08:00
    写一套通用维护 token 的工具 /框架

    使用方从这个框架 Get token 。

    框架内部维护有效期,有个 goroutine 来将快过期的 token 续期。
    CodeJr
        22
    CodeJr  
       2022-06-27 10:31:06 +08:00
    就像 steam pc 和手机 认证一样的采用同样的密钥生成算法
    joesonw
        23
    joesonw  
       2022-06-27 10:50:40 +08:00 via iPhone
    用时间轮,全局一个 ticker 就好了。
    hopingtop
        24
    hopingtop  
       2022-06-27 11:04:22 +08:00
    更新这个操作,分摊到客户端, 去检测你下发 token 的过期 时间戳。他检测到 快 过期,在主动触发 服务端。 然后你 服务端,只需要一个 代价很小的 轮询 补偿机制就行了。 不知道这样能够解决你的问题?
    xtinput
        25
    xtinput  
       2022-06-27 15:04:15 +08:00
    用之前判断有效期进行更新,或者后台返回指定错误码,然后收到错误码之后更新再尝试上一个请求
    SethShi
        26
    SethShi  
       2022-06-27 17:47:44 +08:00
    怕无效请求就这样子:
    A token 请求 -> 没过期正常使用

    A token 请求 -> 过期了 -> 正常返回数据 -> 在 response header 增加一个 token 字段返回 B token -> 客户端所有请求拦截判断 response header 有 token 就更新到本地 做到无痛更新

    A token 过期了, 有并发请求过来, 上锁存储生成的 token 到 redis, 设置过期时间为 3s(自己决定), 3s 内的请求(包含被锁住的那些)直接返回 redis 存储的 token, 3s 后代表全是失效的请求
    dzdh
        27
    dzdh  
       2022-06-27 19:11:10 +08:00
    go 不是自带锁吗
    zhuweiyou
        28
    zhuweiyou  
       2022-06-28 07:20:50 +08:00
    来请求的时候再判断要不要更新,这种场景为什么要主动去轮.
    abctt
        29
    abctt  
       2022-06-30 23:50:21 +08:00 via iPhone
    搞这么麻烦 session 不会用了吗,舍本求末
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2959 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 00:21 PVG 08:21 LAX 17:21 JFK 20:21
    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