gpt4 book ai didi

android - 访问 token 更新 Dagger 和 Retrofit 时更新请求 header

转载 作者:行者123 更新时间:2023-12-03 19:47:00 32 4
gpt4 key购买 nike

我想在网络请求中更新访问 token 。但是使用 Dagger 和 Retrofit 有一些困难。

😢对不起,我的英文不好,所以给你一个例子可能会很清楚。从头开始,我的想法是这样的:

provide an access token saved in shared preference


@Provides
@ForOauth
Preference<String> provideAccessToken(RxSharedPreferences prefs) {
return prefs.getString(PrefsUtils.KEY_ACCESS_TOKEN);
}

use access token to create an interceptor and added into okhttp client


@Provides
@Singleton
@Named("Cached")
public OkHttpClient provideOkHttpClientWithCache(Application application, @ForOauth OauthInterceptor oauthInterceptor) {
...
builder.addInterceptor(oauthInterceptor);
...
}

and I provide the OauthInterceptor instance by its constructor


@Inject
public OauthInterceptor(@ForOauth Preference<String> accessToken) {
this.accessToken = accessToken;
Timber.tag("OauthInterceptor");
}

但是由于 okhttp 客户端是单例的,所以当 prefs 中的访问 token 更新时它不会改变。我认为可能可行的另一种方法是使用自定义范围,如 @ForOauth什么的,但它只是一个粗略的草图......

顺便说一句,我还有一个这样的想法:

get the access token from prefs in the intercept() method , so every time I can have a request header which contains the latest access token.


@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
if (accessToken.isSet()) {
// Preference<String> accessToken
builder.header("Authorization", ACCESS_TYPE + accessToken.get());
} else {
builder.header("Authorization", "Bearer xxxxxx");
}
return chain.proceed(builder.build());
}

但是我还没有真正尝试过这个想法,我认为它是不对的😂

我想知道我是否必须每次都创建一个新的 okhttp 客户端实例,或者我可以更新访问 token 然后 okhttp 客户端单例可以刷新它的拦截器......

所以你能给我一些建议,或者一个简单的工作例子。

提前谢谢😊

最佳答案

嗯,我已经这样做了很多次,并且从未注意到访问 token 刷新没有沿着链向下传递到 OkHttp 的任何问题。这是我在应用程序中使用的典型设置:

@Provides @Singleton
SharedPreferences providePreferences(Context ctx) {
return new SharedPreferences(ctx);
}

@Provides @Singleton
HttpLoggingInterceptor provideLoggingInterceptor(){
return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
}

@Provides @Singleton
OkHttpClient provideClient(HttpLoggingInterceptor interceptor, SharedPreferences prefs){
return new OkHttpClient.Builder()
.addNetworkInterceptor(chain -> {
// Add Auth Header
String token = prefs.accessToken().get();
if(token == null) token = "";

Request request = chain.request().newBuilder().addHeader("Authorization", token).build();
return chain.proceed(request);
})
.addInterceptor(interceptor)
.build();
}

@Provides @Singleton
Retrofit provideRetrofit(@ApiUrl String url, OkHttpClient client){
return new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addConverterFactory(LoganSquareConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
SharedPreferences只是一个类,我抽象了一些 RxSharedPreferences逻辑成。也可以 @Inject它也可以在应用程序中的任何需要它的地方使用,这很好。这是该类的一个简单版本,只是为了好玩:
public class SharedPreferences {
// Constants and variables
private static final String PREFERENCE_FILENAME = BuildConfig.APPLICATION_ID + ".prefs";
private static final String PREF_ACCESS_TOKEN= "pref_access_token";

private RxSharedPreferences mRxSharedPrefs;

// Constructor
public SharedPreferences(Context context) {
mRxSharedPrefs = RxSharedPreferences.create(context.getSharedPreferences(PREFERENCE_FILENAME, Context.MODE_PRIVATE));
}

// Helper methods
public Preference<String> accessToken() { return mRxSharedPrefs.getString(PREF_ACCESS_TOKEN, ""); }

public void logout() { accessToken().delete(); }
}

关于android - 访问 token 更新 Dagger 和 Retrofit 时更新请求 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39136081/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com