android - 刷新令牌时Dagger 2获取旧令牌
问题描述
我遇到了 dagger 2 的问题。简而言之,dagger 2 在我的片段中进行注入,并且令牌是否已过期。TokenAuthenticator 请求保存在 SharedPreferences 中的新令牌。
我的片段没有重新创建,并且 dagger 2 使用过期令牌而不是新令牌进行调用。
现在我将详细解释。
匕首 2
我的匕首 2 逻辑是微不足道的。
网络模块.java
@Provides
@Nullable
String provideAuthToken(Context context) {
return AccountUtils.getCurrentUserToken(context);
}
@Provides
AuthenticationInterceptor provideInterceptor(@Nullable String authToken) {
return new AuthenticationInterceptor(authToken);
}
@Provides
TokenAuthenticator provideAuthenticator(Context context, @Nullable String authToken) {
return new TokenAuthenticator(context, authToken);
}
@Provides
OkHttpClient.Builder provideOkHttpClientBuilder(AuthenticationInterceptor interceptor, TokenAuthenticator authenticator) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.connectTimeout(15, TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(15, TimeUnit.SECONDS);
okHttpClientBuilder.writeTimeout(15, TimeUnit.SECONDS);
if (!okHttpClientBuilder.interceptors().contains(interceptor)) {
okHttpClientBuilder.addInterceptor(interceptor);
okHttpClientBuilder.authenticator(authenticator);
}
return okHttpClientBuilder;
}
它从中获取令牌SharedPreferences
并进行改造以调用 API。
改造电话
然后我对 API 做了一个简单的调用(它是一个带有授权令牌的 GET)
ProfileFragment.java
@Inject
ViewModelFactory viewModelFactory;
UserViewModel userViewModel;
@Override
public void onAttach(Context context) {
((BaseApplication) context.getApplicationContext())
.getAppComponent()
.inject(this);
super.onAttach(context);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
...
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);
userViewModel.getUserInfoMutableLiveData().observe(this, this::consumeResponse);
...
}
private void consumeResponse(UserResponse userResponse) {
switch (userResponse.status) {
case LOADING:
showProgressBar();
break;
case SUCCESS:
handleSuccessResponse(userResponse.data);
break;
case ERROR:
dismissAll();
if (getActivity() != null) {
ResponseHelper.handleErrorResponse(getActivity(), userResponse.error,
mContainer, mMainContainer, this);
}
break;
}
}
刷新令牌
现在让我解释会发生什么。
ProfileFragment 被创建,dagger 2 使用注入通过获取保存在SharedPreferences
.
ProfileFragment 调用 API,由于令牌已过期,它得到 401 错误代码。
调用 TokenAuthenticatior 刷新令牌,它成功刷新令牌并将NEW令牌保存在SharedPreferences
.
再次调用用户信息,但是,由于 ProfileFragment 没有重新创建,它使用具有旧令牌的相同依赖注入进行调用。它使用旧令牌调用 API,然后我们收到错误 401。
如果我现在离开此页面并返回它可以正常工作,因为它会再次进行依赖注入并获取保存在SharedPreferences
.
解决方案
- 这就是为什么我在考虑一些可以再次注射的方法。例如,重新创建配置文件片段,但我认为这不是一个好主意。在使用匕首 2 之前,我对此没有任何问题。
希望有人会提供帮助。谢谢!
解决方案
注入在当前作用域生命周期内发生变化的东西通常是一个坏主意,因为你不能只是再次注入一些东西。正如您所指出的,一旦令牌变得无效,您就必须重新创建整个组件,在这种情况下还强制您重新创建片段。
更好的方法是让你依赖,TokenAuthenticator
然后他们可以根据需要读取和更新令牌。无需将 401 传播给用户,因为您可以在 Authenticator 中静默刷新令牌。AuthenticationInterceptor
AccountUtils
推荐阅读
- python - 尝试添加外部用户但收到以下错误(错误 403:org_Internal)
- python - (x,) 在 NumPy 形状中表示什么?
- javascript - 有没有办法让我的音乐不和谐机器人保存音量设置?
- r - 我可以使用因子作为 mutate 中的搜索和替换值吗?
- laravel - 使用 Vue-pdf 时出现意外的令牌错误
- php - 如何在 PHP 参数 URL 中包含井号 (#)?
- docker - Docker 无法找到文件,即使给出了正确的路径
- scala - 为什么我的 GSON 解串器会为 Option[SomeObject] 引发堆栈溢出?
- java - Java HTTP API 调用 - 流入和流出数据
- javascript - 如何在javascript或表单中用零值替换“未定义”以传递给spring-mvc控制器?