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

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

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

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

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