我将Retrofit2用作Android的HTTP客户端。该应用程序使用访问令牌和刷新令牌与后端进行通信。
场景1:访问令牌已过期,api调用失败,并显示401错误代码,然后我使用Authenticator使用刷新令牌来获取新的一对访问令牌和刷新令牌,并继续使用新的失败呼叫的访问令牌。在稳定的互联网连接下,这一切都很好用
方案2:现在考虑,互联网不稳定,并且不断地掉线。互联网在那里,由于访问令牌过期,api调用失败, 应用程序使用“刷新令牌”进行登录通话,以获取新的一对访问令牌和“刷新令牌”。但是在我获得成功之前,登录电话200掉线了。 现在互联网又回来了,我的应用程序开始再次触发api调用并获得401,然后使用刷新令牌触发新的登录调用。这是问题所在,后端已更新了新的访问和刷新令牌,但由于Internet中断,应用程序从未收到它。由于这个原因,我拥有的刷新令牌不再有效(因为已经在后端创建了一对新令牌并刷新了旧的令牌)
不确定我该如何处理这种情况? 这是我的身份验证器类:
public class MyAuthenticator implements Authenticator {
Context context;
public MyAuthenticator(Context context) {
this.context = context;
}
@Nullable
@Override
public Request authenticate(Route route, Response response) throws IOException {
Retrofit client = new Retrofit.Builder()
.baseUrl(Manager.API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService service = client.create(ApiService.class);
SharedPreferenceManager sharedPreferenceManager = new SharedPreferenceManager(context);
String refreshToken = sharedPreferenceManager.getRefreshToken(context);
AuthRequest authRequest = new AuthRequest();
authRequest.grant_type = "refresh_token";
authRequest.refresh_token = refreshToken;
Call<authResponse> refreshTokenResult = service.refreshToken(authRequest);
retrofit2.Response accessTokenResponse = refreshTokenResult.execute();
//check if response equals 400 , mean empty response
if (accessTokenResponse.isSuccessful()) {
AuthResponse refreshResult = (AuthResponse) accessTokenResponse.body();
//save new access and refresh token
sharedPreferenceManager.writeLoginResponse(context, refreshResult);
// then create a new request and modify it accordingly using the new token
return response.request().newBuilder()
.header("Authorization", "Bearer " + refreshResult.access_token)
.build();
} else {
LoginActivity_.intent(context).flags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK).start();
return null;
}
}
}
不确定我缺少什么以及如何解决该问题。
答案 0 :(得分:0)
您不能在客户端执行任何操作。
您要尝试的是一次完全交付新令牌which is impossible。相反,您应该设计一次交货。
您必须为这种情况准备服务器,即它也应该接受旧的刷新令牌,直到它至少接收一次新的访问令牌或刷新令牌。
在此之前,服务器无法确定客户端是否收到新令牌。