简体   繁体   English

Android进程“静默”使用刷新令牌获取新的访问令牌

[英]Android process for “silently” using refresh token to get new access token

I am currently trying to handle a situation in a demo application I'm writing where I have an expired access token, and I need to use a refresh token to get a new access token. 我目前正在尝试处理我正在编写的演示应用程序中的情况,其中我有一个过期的访问令牌,我需要使用刷新令牌来获取新的访问令牌。 Now for background tasks like this, I'd normally use an AsyncTask like my app currently does for login (which works fine), but I'm not sure how to do this - if it can even be done (I'm sure it can, but I'm just not seeing it right now). 现在对于这样的后台任务,我通常使用像我的应用程序当前用于登录的AsyncTask(工作正常),但我不知道如何做到这一点 - 如果它甚至可以完成(我敢肯定)可以,但我现在没有看到它)。

Below is my current flow - the call to get() blocks the UI thread, which isn't what I'm supposed to be doing here. 下面是我当前的流程 - 对get()的调用阻止了UI线程,这不是我应该在这里做的。 Our access ticket class contains both the access token and refresh token. 我们的访问权限类包含访问令牌和刷新令牌。

public boolean isLoggedIn() {
    if (isFreshAccessToken())
        return true;

    // If the access token is expired, we'll need to use the
    // refresh token to get another one.  Use a background task
    // to do this.
    String refreshToken = preferences.getString(REFRESH_TOKEN_KEY, null);
    if (StringUtils.isNotBlank(refreshToken)) {
        RefreshAccessTokenAsyncTask refreshLogin = new RefreshAccessTokenAsyncTask();
        refreshLogin.execute(refreshToken);

        try {
            return refreshLogin.get();
        } catch (Exception e) {
            Log.d(TAG, "isLoggedIn() : Exception in async task.  Returning false.");
            return false;
        }
    } else
        return false;
}

Here is what my AsyncTask implementation currently looks like. 这是我的AsyncTask实现目前的样子。 The refreshAccessTicket() method simply makes the REST call to get the AccessTicket response. refreshAccessTicket()方法只是进行REST调用以获取AccessTicket响应。

private class RefreshAccessTokenAsyncTask extends AsyncTask<String, Void, Boolean> {

    @Override
    protected Boolean doInBackground(String... params) {
        String refreshToken = params[0];
        try {

            // Get a new access token using the refresh token
            // in the background ...
            AccessTicket accessTicket = refreshAccessTicket(refreshToken);

            // ... and save the updated information to the shared
            // preferences
            saveAccessTicket(accessTicket);
            return true;
        } catch (Exception ex) {

            // If the call for a new access token fails for any reason,
            // return FALSE.  We'll force the user to log in again to
            // get a completely new access ticket.
            return false;
        }
    }

    @Override
    protected void onPostExecute(Boolean isLoggedIn) {
        super.onPostExecute(isLoggedIn);
        Log.d(TAG, "RefreshAccessTokenAsyncTask.onPostExecute() : " +
                "Returning isLoggedIn value of " + isLoggedIn);
    }

}

What am I missing here? 我在这里错过了什么? As I mentioned above, I want this process to be silent - if the access token has expired, I want to use the refresh token to automatically get a new access token without the user having to do anything or have the app jump out of the current flow (such as getting a friends list, etc.) - it will happen in the background. 正如我上面提到的,我希望这个过程是静默的 - 如果访问令牌已经过期, 我想使用刷新令牌自动获取新的访问令牌,而无需用户做任何事情或让应用程序跳出当前流程 (例如获取朋友列表等) - 它将在后台发生。 Should I be using something other than AsyncTask? 我应该使用AsyncTask以外的东西吗?

AsyncTask should work fine, but you can't get the result like that. AsyncTask应该可以正常工作,但你不能得到那样的结果。 Try something like this instead. 尝试这样的事情。

private interface Callback {
void done(boolean result);
}

private class RefreshAccessTokenAsyncTask extends AsyncTask<String, Void, Boolean> {

private Callback cb;

private RefreshAccessTokenAsyncTask(Callback callback)
    cb = callback;
}

@Override
protected Boolean doInBackground(String... params) {
    String refreshToken = params[0];
    try {

        // Get a new access token using the refresh token
        // in the background ...
        AccessTicket accessTicket = refreshAccessTicket(refreshToken);

        // ... and save the updated information to the shared
        // preferences
        saveAccessTicket(accessTicket);
        return true;
    } catch (Exception ex) {

        // If the call for a new access token fails for any reason,
        // return FALSE.  We'll force the user to log in again to
        // get a completely new access ticket.
        return false;
    }
}

@Override
protected void onPostExecute(Boolean isLoggedIn) {
    super.onPostExecute(isLoggedIn);
    Log.d(TAG, "RefreshAccessTokenAsyncTask.onPostExecute() : " +
            "Returning isLoggedIn value of " + isLoggedIn);
    cb.done(isLoggedIn);
}

} }

Then use the AsyncTask like so: 然后像这样使用AsyncTask:

public boolean isLoggedIn() {
if (isFreshAccessToken())
    return true;

// If the access token is expired, we'll need to use the
// refresh token to get another one.  Use a background task
// to do this.
String refreshToken = preferences.getString(REFRESH_TOKEN_KEY, null);
if (StringUtils.isNotBlank(refreshToken)) {
    Callback callback = new Callback() {
        public void done(boolean result){
            // whatever you need to do here
        }
    }
    RefreshAccessTokenAsyncTask refreshLogin = new RefreshAccessTokenAsyncTask(callback);
    refreshLogin.execute(refreshToken);
} else
    return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM