Android Retrofit 2.0 Refresh Tokens(Android Retrofit 2.0更新令牌)

本文介绍了Android Retrofit 2.0更新令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Retrofit 2.0WITHJackson转换器与睡觉接口通信。某些请求在授权时需要令牌。如果我拥有的令牌已过期,我需要用另一个请求刷新它们,并重复因此而失败的上一个请求。

我的问题:我每次都需要手动完成吗?或者有什么方法可以自动完成吗?

我目前的实现方式如下:

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。你可以用它。这里有一个链接: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响应。

Square的Interceptor文档:OkHttp Interceptors

Square的Authenticator文档:OkHttp handling-authentication

我知道这里没有代码,但请查看链接并编辑您的问题,然后我将尝试帮助您。

这篇关于Android Retrofit 2.0更新令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!