Android-使用刷新令牌刷新访问令牌

时间:2019-09-07 10:29:08

标签: java android

我在刷新访问令牌时遇到问题。如果响应为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;
    }

我想听听您的建议。预先感谢。

0 个答案:

没有答案