Android 改造和 JWT 身份验证
Android Retrofit and JWT authentication
我正在使用 JWT 身份验证并将身份验证令牌存储在共享首选项中。我找不到向改造客户端添加授权 header 的方法。这就是为什么我的网络调用第一次收到 401 错误,从第二次开始。如何解决?
@Module
public class AppRetrofitModule {
private static final String TAG = "AppRetrofitModule";
private static Retrofit.Builder builder
= new Retrofit.Builder()
.baseUrl(Config.REST_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
private static OkHttpClient.Builder httpClient
= new OkHttpClient.Builder();
private static HttpLoggingInterceptor logging
= new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BASIC);
@Singleton
@Provides
public Retrofit provideRetrofit(AppPreferencesHelper appPreferencesHelper) {
String authToken = "Bearer " + appPreferencesHelper.getAccessToken();
Log.d(TAG, "provideRetrofit: " + authToken);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Response response = chain.proceed(original);
Request request = original.newBuilder()
.header("Authorization", authToken)
.method(original.method(), original.body()).build();
return chain.proceed(request);
}
});
if (!httpClient.interceptors().contains(logging)) {
httpClient.addInterceptor(logging);
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.callTimeout(60, TimeUnit.SECONDS);
builder.client(httpClient.build());
retrofit = builder.build();
}
return retrofit;
}
}
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Response response = chain.proceed(original);
String authToken = "Bearer " + appPreferencesHelper.getAccessToken();
Request request = original.newBuilder()
.header("Authorization", authToken)
.method(original.method(), original.body()).build();
return chain.proceed(request);
}
});
if (!httpClient.interceptors().contains(logging)) {
httpClient.addInterceptor(logging);
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.callTimeout(60, TimeUnit.SECONDS);
builder.client(httpClient.build());
retrofit = builder.build();
}
return retrofit;
之前我在拦截器之外获取 authToken 时犯了错误。但它需要在拦截器内部获取,以便我们也可以在第一时间获取令牌。它在第二次 API 调用之前工作,因为 authToken 值得到刷新。
我正在使用 JWT 身份验证并将身份验证令牌存储在共享首选项中。我找不到向改造客户端添加授权 header 的方法。这就是为什么我的网络调用第一次收到 401 错误,从第二次开始。如何解决?
@Module
public class AppRetrofitModule {
private static final String TAG = "AppRetrofitModule";
private static Retrofit.Builder builder
= new Retrofit.Builder()
.baseUrl(Config.REST_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
private static OkHttpClient.Builder httpClient
= new OkHttpClient.Builder();
private static HttpLoggingInterceptor logging
= new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BASIC);
@Singleton
@Provides
public Retrofit provideRetrofit(AppPreferencesHelper appPreferencesHelper) {
String authToken = "Bearer " + appPreferencesHelper.getAccessToken();
Log.d(TAG, "provideRetrofit: " + authToken);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Response response = chain.proceed(original);
Request request = original.newBuilder()
.header("Authorization", authToken)
.method(original.method(), original.body()).build();
return chain.proceed(request);
}
});
if (!httpClient.interceptors().contains(logging)) {
httpClient.addInterceptor(logging);
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.callTimeout(60, TimeUnit.SECONDS);
builder.client(httpClient.build());
retrofit = builder.build();
}
return retrofit;
}
}
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Response response = chain.proceed(original);
String authToken = "Bearer " + appPreferencesHelper.getAccessToken();
Request request = original.newBuilder()
.header("Authorization", authToken)
.method(original.method(), original.body()).build();
return chain.proceed(request);
}
});
if (!httpClient.interceptors().contains(logging)) {
httpClient.addInterceptor(logging);
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.callTimeout(60, TimeUnit.SECONDS);
builder.client(httpClient.build());
retrofit = builder.build();
}
return retrofit;
之前我在拦截器之外获取 authToken 时犯了错误。但它需要在拦截器内部获取,以便我们也可以在第一时间获取令牌。它在第二次 API 调用之前工作,因为 authToken 值得到刷新。