我正在使用 Retrofit 2.0
和 Jackson
转换器与Rest API进行通信 . 某些请求需要授权令牌 . 如果我拥有的令牌已过期,我需要用另一个请求刷新它们并重复上次因此而失败的请求 .
我的问题:我每次都需要手动完成它还是有任何方法可以自动化它?
这是我现在实现它的方式:
TrackerService
public interface TrackerService {
@POST("auth/sendPassword")
Call<ResponseMessage> sendPassword(@Header("app-type") String appType,
@Body User userMobile);
@FormUrlEncoded
@POST("oauth/token")
Call<TokenResponse> oathToken(@Field("client_id") String clientId,
@Field("client_secret") String clientSecret,
@Field("grant_type") String grantType,
@Field("username") String username,
@Field("password") String password);
@FormUrlEncoded
@POST("oauth/token")
Call<TokenResponse> refreshToken(@Field("client_id") String clientId,
@Field("client_secret") String clientSecret,
@Field("grant_type") String grantType,
@Field("refresh_token") String username);
@PUT("me/profile")
Call<Profile> updateProfile(@Header("app-type") String appType,
@Header("Authorization") String token,
@Body Profile profile);
}
ServiceGateway
public class ServiceGateway {
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit retrofit;
public static <S> S createService(Class<S> serviceClass) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20 * 1000, TimeUnit.MILLISECONDS)
.writeTimeout(20 * 1000, TimeUnit.MILLISECONDS)
.readTimeout(20 * 1000, TimeUnit.MILLISECONDS)
.addInterceptor(interceptor).build();
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(JacksonConverterFactory.create());
retrofit = builder.client(httpClient.build())
.client(client)
.build();
return retrofit.create(serviceClass);
}
public static Retrofit getRetrofit() {
return retrofit;
}
}
How I call function and treat it when tokens are out of date
trackerService = ServiceGateway.createService(TrackerService.class);
Call<Profile> call = trackerService.updateProfile(getString(R.string.app_type), "Bearer " + userPrefs.accessToken().get(),
new Profile(trimedInvitationMessage, title,
String.valueOf(selectedCountry.getCountryCode()), mobilePhone, countryISO, fullName));
call.enqueue(new Callback<Profile>() {
@Override
public void onResponse(Call<Profile> call, Response<Profile> response) {
if (response.body() != null) {
} else {
if (response.raw().code() == 401) {
Call<TokenResponse> refreshTokenCall = trackerService.refreshToken(userPrefs.clientId().get(),
userPrefs.clientSecret().get(), "refresh_token", userPrefs.refreshToken().get());
refreshTokenCall.enqueue(new Callback<TokenResponse>() {
@Override
public void onResponse(Call<TokenResponse> call, Response<TokenResponse> response) {
if (response.body() != null) {
updateAdviserProfile(trimedInvitationMessage, title, mobilePhone, countryISO, fullName);
} else {
userPrefs.clear();
Intent intent = new Intent(WelcomeActivity_.launcher(EditProfileActivity.this));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
startActivity(WelcomeActivity_.launcher(EditProfileActivity.this));
}
}
@Override
public void onFailure(Call<TokenResponse> call, Throwable t) {
}
});
} else if (response.raw().code() == 422)
}
}
@Override
public void onFailure(Call<Profile> call, Throwable t) {
}
});
1 回答
我在2-3个月前搜索过这个话题,发现
OkHttp 's Authenticator
. 你可以使用它 . 这里有一个链接:refreshing-oauth-token-using-retrofit-without-modifying-all-calls它的工作方式如下:如果您的请求返回
401
,则Authenticator
移入,并刷新您的令牌 . 但不要忘记return null
或任何尝试限制 . 如果您没有限制,它将在刷新请求失败时尝试刷新多次,并在刷新令牌时进行同步请求 .我也有一个问题和答案 - 我自己通过搜索theese链接写的 - 关于刷新Oauth2令牌,也许你会看看它:
问题:android-retrofit2-refresh-oauth-2-token
答案:android-retrofit2-refresh-oauth-2-token-answer
Additionally: 例如,如果您有令牌,则需要每3小时刷新一次 . 你也可以写一个
Interceptor
. 在Interceptor
中:比较时间并刷新令牌而不获取任何401
响应 .你可以阅读
Interceptor
页:OkHttp Interceptors你也可以看看那里:OkHttp handling-authentication
我知道这里没有代码,但尝试链接并编辑您的问题然后我会帮助您 .