簡體   English   中英

在 OkHttp 攔截器中刷新令牌

[英]Refresh a token in OkHttp Interceptor

我正在編寫一個攔截器,這樣當我得到 401 時,我會使用刷新令牌在后台獲取新的訪問令牌,然后將該令牌添加到請求中。

代碼示例:

    @Override
    public Response intercept(final Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);

        if (response.code() != 200) {
            try {
                new TokenRequestTask(tokenRequest, request, OkHttpresponse, chain).execute().get(5000, TimeUnit.MILLISECONDS);
                response = chain.proceed(request);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }
        return response;
    }

在異步任務中postExecution ,我通過添加收到的新身份驗證令牌來更改請求的標頭。 但問題是輸出不符合預期。 該函數返回舊響應,因為異步任務的結果在此之后。 理想情況下,它應該等待異步任務結果然后返回但沒有發生。 如何實現這一目標

我在另一個線程上使用協議緩沖區來獲取 getRefreshToken 並成功做到了! 這是我的代碼:

public class IgapRetrofitInterceptor implements Interceptor {

private boolean isRefreshing;

private TokenContainer tokenContainer = TokenContainer.getInstance();

@NotNull
@Override
public Response intercept(Chain chain) throws IOException {
    Request original = chain.request();
    Request request = chain.request();

    Request.Builder builder = request.newBuilder();
    builder.header("Authorization", tokenContainer.getToken());
    builder.header("Content-Type", "application/json");
    builder.method(original.method(), original.body());

    String token = tokenContainer.getToken();

    request = builder.build();
    Response response = chain.proceed(request);

    if (response.code() == 401) {
        synchronized (this) {
            Log.e("refreshToken", "Failed " + request.toString() + " with token -> " + tokenContainer.getToken());

            String currentToken = tokenContainer.getToken();

            if (currentToken != null && currentToken.equals(token)) {
                try {
                    getRefreshToken(); //aysnc
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            if (tokenContainer.getToken() != null) {
                builder.header("Authorization", tokenContainer.getToken());
                request = builder.build();
                Log.e("refreshToken", "Send " + request.toString() + " again with new token -> " + tokenContainer.getToken());
                Log.e("refreshToken", "--------------------------------------------------------------------------------");
                return chain.proceed(request);
            }
        }
    }

    Log.i("refreshToken", "req 200 with token -> " + tokenContainer.getToken());

    return response;
}

public synchronized void getRefreshToken() throws InterruptedException {
    if (!isRefreshing) {

        isRefreshing = true;

        Log.e("refreshToken", "Refreshing token...");
        tokenContainer.getRefreshToken(() -> {
            synchronized (IgapRetrofitInterceptor.this) {
                isRefreshing = false;
                Log.e("refreshToken", "Proto response on success and token updated with token -> " + tokenContainer.getToken());
                IgapRetrofitInterceptor.this.notifyAll();
            }
        });
    }

    Log.e("refreshToken", "lock thread -> " + android.os.Process.getThreadPriority(android.os.Process.myTid()) + this.toString());
    this.wait();
    Log.e("refreshToken", "unlock thread -> " + android.os.Process.getThreadPriority(android.os.Process.myTid()) + this.toString());

 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM