我们在Android应用中使用Retrofit与OAuth2安全服务器进行通信 . 一切都很好,我们使用RequestInterceptor在每次调用时包含访问令牌 . 但是,有时候,访问令牌将过期,并且需要刷新令牌 . 当令牌过期时,下一个调用将返回一个未授权的HTTP代码,因此很容易监控 . 我们可以通过以下方式修改每个Retrofit调用:在失败回调中,检查错误代码,如果它等于Unauthorized,则刷新OAuth令牌,然后重复Retrofit调用 . 但是,为此,应该修改所有呼叫,这不是一个易于维护的,并且是一个很好的解决方案 . 有没有办法在不修改所有Retrofit调用的情况下执行此操作?
8 回答
请不要使用
Interceptors
来处理身份验证 .目前,处理身份验证的最佳方法是使用专为this purpose设计的新Authenticator API .
当响应是
401 Not Authorised
retrying last failed request 时,OkHttp将 automatically askAuthenticator
用于凭据 .将
Authenticator
附加到OkHttpClient
,方法与Interceptors
相同创建
Retrofit
RestAdapter
时使用此客户端如果您正在使用Retrofit> =
1.9.0
,则可以使用OkHttp's中引入的OkHttp's新Interceptor . 你会想要使用Application Interceptor,它允许你retry and make multiple calls
.你的拦截器可能看起来像这个伪代码:
定义
Interceptor
后,创建一个OkHttpClient
并将拦截器添加为Application Interceptor .最后,在创建
RestAdapter
时使用此OkHttpClient
.Warning: 由于
Jesse Wilson
(来自Square)提到here,这是一种危险的权力 .话虽如此,我绝对认为这是现在处理这类事情的最好方法 . 如果您有任何疑问,请随时在评论中提问 .
如果你有
Authenticator
中需要的RetrofitTokenService
,但你只想设置一个OkHttpClient
,你可以使用TokenServiceHolder
作为TokenAuthenticator
的依赖 . 您必须在应用程序(单例)级别维护对它的引用 . 如果您使用Dagger 2,这很容易,否则只需在您的应用程序中创建类字段 .在
TokenAuthenticator.java
在
TokenServiceHolder.java
:客户端设置:
如果你正在使用Dagger 2或类似的依赖注入框架,那么在this question的答案中有一些例子 .
我知道这是一个旧线程,但万一有人偶然发现它 .
我遇到了同样的问题,但我想只创建一个OkHttpClient因为我认为我不需要另一个只用于TokenAuthenticator本身,我使用的是Dagger2,所以我最终在TokenAuthenticator中提供服务类为 Lazy injected ,你可以在dagger 2 here中阅读更多关于懒惰注射的信息,但它基本上就是说要让Dagger去 NOT 并立即创建TokenAuthenticator所需的服务 .
您可以参考此SO线程获取示例代码:How to resolve a circular dependency while still using Dagger2?
您可以尝试为所有加载器创建一个基类,您可以在其中捕获特定异常,然后根据需要进行操作 . 使所有不同的加载器从基类扩展,以传播行为 .
经过长期研究,我定制了Apache客户端来处理刷新AccessToken For Retrofit,其中您将访问令牌作为参数发送 .
使用cookie Persistent Client启动适配器
Cookie持久客户端维护所有请求的cookie并检查每个请求响应,如果是未授权访问ERROR_CODE = 401,刷新访问令牌并调用请求,否则只处理请求 .
对于想要在刷新令牌时解决并发/并行调用的任何人 . 这是一个解决方法
像_theblang一样使用
TokenAuthenticator
回答是处理refresh_token
的正确方法 .这是我的工具(我使用过Kotlin,Dagger,RX但是你可以用这个想法实现你的情况)
TokenAuthenticator
为防止 dependency cycle 喜欢@Brais Gabin评论,我创建 2 界面就像
和
AccessTokenWrapper 班
AccessToken 上课
My Interceptor
最后,添加
Interceptor
创建服务时OKHttpClient
和OKHttpClient
PotoAuthApi演示
https://github.com/PhanVanLinh/AndroidMVPKotlin
注意
验证器流程
示例API
getImage()
返回401错误代码TokenAuthenticator
里面的authenticate
方法将 fired同步
noneAuthAPI.refreshToken(...)
已调用noneAuthAPI.refreshToken(...)
响应后 - >新标记将添加到 HeadersgetImage()
将 AUTO called 带新 Headers (HttpLogging
WILL NOT log 此次通话)(intercept
内AuthInterceptor
WILL NOT CALLED )如果
getImage()
仍然失败,错误401,TokenAuthenticator
中的authenticate
方法将 fired AGAIN and AGAIN 那么它将多次抛出有关调用方法的错误(java.net.ProtocolException: Too many follow-up requests
) . 您可以通过count response来阻止它 . 例如,如果在authenticate
中return null
重试3次后,getImage()
将 finish 和return response 401
如果
getImage()
响应成功=>我们将正常结果(就像你没有错误地调用getImage()
)希望它有所帮助