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

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

如果要优雅可以借助相关的注解:cache 和 retry 都有注解可以使用。保证代码美美的
menglddd
2023-05-05 16:39:03 +08:00
拦截器+retryer
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
2023-05-05 16:48:42 +08:00
1. 封装调用第三方的接口
2. 在封装中响应处理时根据第三方系统的错误信息判断是否可以处理,譬如过期
3. 将 token 存储到 redis 或者服务内存中,微服务架构建议存 redis 中
4. 如果发生 token 失效,就重新获取 token 并存储,且重新调用接口 (记得设置重试上限)
Habyss
2023-05-05 18:05:19 +08:00
1. token 放在有过期时间的缓存中
2. 所有需要 token 的地方, 统一调用一个方法获取 token
3. 在获取 token 的方法内 先去缓存拿 token, 如果没有, 则获取新的 token, 并重新设置缓存(拥有过期时间), 返回新的 token.(加不加锁看自己项目情况)
4. 这不就是相当于无感调用, 而且没有[返回前端提示失败], 除非获取 token 的第三方接口出错
pepesii
2023-05-05 18:12:59 +08:00
不会 java , 但是问题很普遍啊,token 给你的时候,是有 expiretime 的吧,你把这个记着(缓存?),在每次使用前判断下过期了没有,然后过期了重新拿,没过期就直接用,这样...
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
2023-05-05 23:21:20 +08:00
和第三方沟通,为啥要调用返回才知道 token 过期了,不能给个过期时间,好让对接方定时任务提前刷好?
009694
2023-05-05 23:58:41 +08:00
我启了单独的协程单独维护 token😂
BugCry
2023-05-06 10:01:22 +08:00
我写了个定时任务,把 token 刷新到 consul 中,下游会自动监听变化
zhongpingjing
2023-05-06 11:36:08 +08:00
用 guava 的缓存实现就好了,可以配置定时刷新,只要把刷新的间隔小于有效时间就可以一直有效
codeMore
2023-05-06 17:05:47 +08:00
我们是写了个 token 中控服,
1 、所有需要调用三方获取 token 的都调该中控服,由中控服去获取最新的 token ,并缓存再中控服内,
2 、如果某个业务使用处发现这个 token 过期了,那么就携带该过期 token 去请求中控服,中控服判断如果传入的 token 和缓存的 token 一致,那么就再去渠道刷一个最新的 token 缓存并返回。
3 、中控服缓存的过期时间比渠道返回的过期时间小 1-2 分钟,这样可以做到提前刷新,用户侧就不会感知到 token 过期的情况
yusheng88
2023-05-09 19:48:05 +08:00
我在项目中的实现:
https://blog.csdn.net/qq_40272936/article/details/130587204
通常搭配过滤器、拦截器使用,体验比定时任务好.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/937581

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX