私は使っている Retrofit 2.0
Rest APIとの通信用のJackson
コンバーター付き。一部のリクエストでは、承認時にトークンが必要です。持っているトークンが古い場合、別のリクエストでトークンを更新し、そのために失敗した最後のリクエストを繰り返す必要があります。
私の質問:毎回手動で行う必要がありますか、それを自動化する方法はありますか?
現時点での実装方法は次のとおりです。
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;
}
}
トークンが古くなったときに関数を呼び出して処理する方法
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) {
}
});
2〜3か月前からこのトピックを検索し、OkHttp 's Authenticator
を見つけました。使用できます。ここに1つのリンクがあります: refreshing-oauth-token-using-retrofit-without-modifying-all-calls
次のように機能します。リクエストが401
を返す場合、Authenticator
が移動し、トークンを更新します。ただし、return null
を忘れないでください。または、制限を設定してください。制限しない場合、更新要求が失敗すると複数回更新が試行され、トークンを更新すると同期要求が作成されます。
また、Oauth2トークンの更新に関する質問と回答(両方とも、これらのリンクを検索して自分で作成したもの)があります。
質問: Android-retrofit2-refresh-oauth-2-token
回答: Android-retrofit2-refresh-oauth-2-token-answer
さらに:たとえば、トークンがあり、3時間ごとに更新する必要がある場合。 Interceptor
も記述できます。 Interceptor
:時間を比較し、401
応答を取得せずにトークンを更新します。
Interceptor
ページを読むことができます: OkHttp Interceptors
こちらもご覧ください: OkHttp handling-authentication
ここにはコードがないことを知っていますが、リンクを試して質問を編集してください。