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

如何优雅的刷新第三方接口的 token

  •  1
     
  •   yoloMiss · 2023-05-05 16:04:46 +08:00 · 4070 次点击
    这是一个创建于 569 天前的主题,其中的信息可能已经有所发展或是发生改变。
    java 大佬们:
    如题所示,最近搞的小项目需要调用第三方接口,接口需要传递公共参数 token ( token 有过期时间)目前的做法是在项目启动的时候正常请求拿到 token ,放到本地缓存里。
    目前逻辑是,如果调用第三方接口的时候返回 token 过期了就重新调用获取 token 接口并返回前端提示失败(提示用户稍后重试)。
    但是感觉这样写很麻烦,因为调用的地方和接口数量太多了。怎么才能做到统一处理或者拦截?做到类似于前端 token 无感刷新
    第 1 条附言  ·  2023-05-05 23:06:54 +08:00
    补充一下:没有 Expiretime 间和可以用来刷新 AccessToken 的 RefershToken 。
    22 条回复    2023-05-16 10:41:21 +08:00
    hhjswf
        1
    hhjswf  
       2023-05-05 16:08:32 +08:00
    第三方有没提供刷新 token 的接口?
    Aaronsunny
        2
    Aaronsunny  
       2023-05-05 16:08:34 +08:00
    第三方这个接口不返回过期时间吗?
    unco020511
        3
    unco020511  
       2023-05-05 16:08:58 +08:00
    拦截器,调用方是无感的
    LeegoYih
        4
    LeegoYih  
       2023-05-05 16:09:00 +08:00
    获取了新 token ,旧 token 还能不能用?
    如果可以就启动一个定时任务,比超时时间提前几分钟获取新 token ,这样过程中也不会影响其他人使用。
    如果不可以,那就没有其他更好的方案,都差不多
    28Sv0ngQfIE7Yloe
        5
    28Sv0ngQfIE7Yloe  
       2023-05-05 16:10:06 +08:00
    对缓存搞个异步的 reflasher
    rm0gang0rf
        6
    rm0gang0rf  
       2023-05-05 16:11:11 +08:00
    第三方有没提供刷新 token 的接口?
    binge921
        7
    binge921  
       2023-05-05 16:22:55 +08:00
    拦截器 或者 过滤器 拿到 token 比对过期时间 如果失效就重新获取 或者要求第三方 api 提供刷新 token 接口 或者根据第三方 api 的 token 过期时间 进行时间段内的定时任务批量刷新 才疏学浅 我能想到的就这些了
    rizon
        8
    rizon  
       2023-05-05 16:32:43 +08:00
    1. 一般都会提供 refresh 接口,独立的定时任务刷新一下就好。
    2. 在 cacheManager 中,当 get 缓存时,检查缓存的过期时间马上到了,就在返回旧 token 的同时,异步刷新新的 token 。
    3. 如果缓存连过期时间都没有,在调用业务接口地方,当 catch 到 token 失效的返回值之后,自动完成一次 retry 操作。

    如果要优雅可以借助相关的注解:cache 和 retry 都有注解可以使用。保证代码美美的
    menglddd
        9
    menglddd  
       2023-05-05 16:39:03 +08:00
    拦截器+retryer
    james2013
        10
    james2013  
       2023-05-05 16:42:41 +08:00
    第 1 种方法:每个调用第三方接口均调用同 1 个获取 token 方法 a,a 方法使用锁,在 a 方法进行逻辑判断:token 不存在或者过期,则调用第 3 方刷新 token 接口,记录 token 过期时间
    第 2 种方法:如果是 retrofit 或者 okhttp 网络框架请求第三方,本身有拦截器,在拦截器中判断接口前缀是第 3 方并且不是刷新 token 的接口则进行统一的逻辑判断
    luomao
        11
    luomao  
       2023-05-05 16:48:42 +08:00
    1. 封装调用第三方的接口
    2. 在封装中响应处理时根据第三方系统的错误信息判断是否可以处理,譬如过期
    3. 将 token 存储到 redis 或者服务内存中,微服务架构建议存 redis 中
    4. 如果发生 token 失效,就重新获取 token 并存储,且重新调用接口 (记得设置重试上限)
    Habyss
        12
    Habyss  
       2023-05-05 18:05:19 +08:00
    1. token 放在有过期时间的缓存中
    2. 所有需要 token 的地方, 统一调用一个方法获取 token
    3. 在获取 token 的方法内 先去缓存拿 token, 如果没有, 则获取新的 token, 并重新设置缓存(拥有过期时间), 返回新的 token.(加不加锁看自己项目情况)
    4. 这不就是相当于无感调用, 而且没有[返回前端提示失败], 除非获取 token 的第三方接口出错
    pepesii
        13
    pepesii  
       2023-05-05 18:12:59 +08:00
    不会 java , 但是问题很普遍啊,token 给你的时候,是有 expiretime 的吧,你把这个记着(缓存?),在每次使用前判断下过期了没有,然后过期了重新拿,没过期就直接用,这样...
    noparking188
        14
    noparking188  
       2023-05-05 21:12:46 +08:00
    https://github.com/simple-salesforce/simple-salesforce/blob/6e0ab819afed6680b90edf993370ad22bb5bce24/simple_salesforce/api.py#L583

    看看这个实现也不错,统一 API 调用的入口。我用过装饰器实现也还行,原理一样,报错重试,Java 的注解是不是能实现类似 Python 装饰器的作用
    oneisall8955
        15
    oneisall8955  
       2023-05-05 23:21:20 +08:00 via Android
    和第三方沟通,为啥要调用返回才知道 token 过期了,不能给个过期时间,好让对接方定时任务提前刷好?
    009694
        16
    009694  
       2023-05-05 23:58:41 +08:00 via iPhone
    我启了单独的协程单独维护 token😂
    BugCry
        17
    BugCry  
       2023-05-06 10:01:22 +08:00
    我写了个定时任务,把 token 刷新到 consul 中,下游会自动监听变化
    zhongpingjing
        18
    zhongpingjing  
       2023-05-06 11:36:08 +08:00
    用 guava 的缓存实现就好了,可以配置定时刷新,只要把刷新的间隔小于有效时间就可以一直有效
    codeMore
        19
    codeMore  
       2023-05-06 17:05:47 +08:00
    我们是写了个 token 中控服,
    1 、所有需要调用三方获取 token 的都调该中控服,由中控服去获取最新的 token ,并缓存再中控服内,
    2 、如果某个业务使用处发现这个 token 过期了,那么就携带该过期 token 去请求中控服,中控服判断如果传入的 token 和缓存的 token 一致,那么就再去渠道刷一个最新的 token 缓存并返回。
    3 、中控服缓存的过期时间比渠道返回的过期时间小 1-2 分钟,这样可以做到提前刷新,用户侧就不会感知到 token 过期的情况
    yusheng88
        20
    yusheng88  
       2023-05-09 19:48:05 +08:00
    我在项目中的实现:
    https://blog.csdn.net/qq_40272936/article/details/130587204
    通常搭配过滤器、拦截器使用,体验比定时任务好.
    ThreeK
        21
    ThreeK  
       2023-05-16 10:35:58 +08:00
    自己写个 getToken 方法不就行了,返回前判断下刷新时间,到了刷新时间就去刷新再取一次,没有到就直接返回缓存里的。要是像我之前对接京东 e 卡,新老 token 在过期前都能用,这个方法并发都不需要考虑。
    ThreeK
        22
    ThreeK  
       2023-05-16 10:41:21 +08:00
    我日,没有过期时间、刷新时间啊,那就没法了。只能自己根据经验设置个时间看多久去触发一次刷新 token ,尽量少出现 token 过期,再就是统一异常拦截 token 过期的异常兜个底。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2752 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 08:16 · PVG 16:16 · LAX 00:16 · JFK 03:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.