我在刷新访问令牌时遇到问题。如果响应为401-未经授权,我尝试刷新访问令牌。我使用添加到OkHttpClient的TokenAuthenticator进行此操作。但是,如果多次刷新令牌请求发送到服务器,我将丢失身份验证。通常,超过5个请求以不同的片段发送到我的应用程序中的服务器。我试图通过同步来处理它,但没有解决我的问题。
TokenAuthenticator.java
public class TokenAuthenticator implements Authenticator {
private final Context context;
private AccountManager accountManager;
public TokenAuthenticator(Context context) {
this.context = context;
this.accountManager = new AccountManager(context);
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
synchronized (context){
String userRefreshToken = accountManager.getStringPreference(accountManager.KEY_REFRESH_TOKEN);
boolean refreshResult = refreshToken(BASE_URL, userRefreshToken, user_type);
if (refreshResult) {
return response.request().newBuilder()
.header("Authorization", accountManager.getHeader())
.build();
} else {
AccountManager.openLoginPage(context);
return null;
}
}
}
private boolean refreshToken(String url, String refresh, String cid) throws IOException {
URL refreshUrl = new URL(url + "token");
HttpURLConnection urlConnection = (HttpURLConnection) refreshUrl.openConnection();
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setUseCaches(false);
String urlParameters = "grant_type=refresh_token&client_id=" + cid + "&refresh_token=" + refresh;
urlConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Gson gson = new Gson();
Authenticate refreshTokenResult = gson.fromJson(response.toString(), Authenticate.class);
accountManager.saveAuthenticationDetails(refreshTokenResult);
Log.e("TokenAuthenticator",urlConnection.getResponseMessage()+" "+urlConnection.getResponseCode());
return true;
} else {
Log.e("TokenAuthenticator",urlConnection.getResponseMessage()+" "+urlConnection.getResponseCode());
return false;
}
}
}
ApiClient.java
public static Retrofit getClient(Context context) {
if (retrofit == null) {
TokenAuthenticator tokenAuthenticator = new TokenAuthenticator(context);
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(1);
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okClient = new OkHttpClient.Builder()
.authenticator(tokenAuthenticator)
.dispatcher(dispatcher)
.addInterceptor(interceptor)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return retrofit;
}
我想听听您的建议。预先感谢。