简体   繁体   English

从Volley中的刷新令牌获取访问令牌

[英]Get access token from refresh token in Volley

I am using Android Volley to send an HTTP request to the blogger API website to get the user's blog: 我正在使用Android Volley将HTTP请求发送到Blogger API网站以获取用户的博客:

https://www.googleapis.com/blogger/v3/users/self/blogs https://www.googleapis.com/blogger/v3/users/self/blogs

I sent a Volley request to this website with an HTTP Authorization header with bearer Access token as said in the documentation: 如文档所述,我向带有HTTP Authorization header的Volley请求发送到此网站,该Authorization header带有bearer Access token

GET https://www.googleapis.com/blogger/v3/users/self/blogs
Authorization: /* OAuth 2.0 token here */

I sent the request like this: 我发送了这样的请求:

RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://www.googleapis.com/blogger/v3/users/self/blogs";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // handle response
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toasty.warning(SelectBlog.this, error.getMessage(), Toast.LENGTH_LONG).show();
        }
    }){
        @Override
        public Map<String, String> getHeaders() {
            HashMap<String, String> params = new HashMap<>();

            params.put("Authorization", "Bearer ACCESS TOKEN");

            return params;
        }
    };

    queue.add(stringRequest);

Now everything seems fine but I see that the access token changes every 3599 seconds. 现在一切似乎都很好,但是我看到访问令牌每3599秒更改一次。 I want to know to update the access token programmatically using refresh token provided by the OAuth Playground website. 我想知道使用 OAuth Playground网站提供的refresh token编程方式更新访问令牌

You probably got your refresh token when you were issued with your access token. 当您获得访问令牌后,您可能会获得刷新令牌。

{
  "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in":3920,
  "token_type":"Bearer",
  "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Above is a sample response for the token request. 上面是令牌请求的示例响应。 You should store this refresh token somewhere safe so that you can refresh your access token without another authentication process via google login. 您应该将此刷新令牌存储在安全的地方,以便无需通过Google登录进行其他身份验证即可刷新访问令牌。

Don't try to refresh your access token periodically. 不要尝试定期刷新访问令牌。 Your logic should not depend on its expiration time because the policy might change later. 您的逻辑不应取决于其到期时间,因为该策略以后可能会更改。

Just try to refresh it when you actually get 401 error from any API response. 当您实际上从任何API响应中收到401错误时,只需尝试刷新它即可。 Therefore what I would do is try to refresh access token when you encounter 401 http status code (which usually means the token has expired) in the onErrorResponse method of your volley request. 因此,我要做的是在凌空请求的onErrorResponse方法中遇到401 http状态代码(通常表示令牌已过期)时尝试刷新访问令牌。

https://developers.google.com/identity/protocols/OAuth2InstalledApp https://developers.google.com/identity/protocols/OAuth2InstalledApp

In the above link, you can find information on how to refresh your access token. 在上面的链接中,您可以找到有关如何刷新访问令牌的信息。 In the Refreshing an access token section, it shows a sample request. 刷新访问令牌部分中,它显示了一个示例请求。

POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=<your_client_id>&
client_secret=<your_client_secret>&
refresh_token=<refresh_token>&
grant_type=refresh_token

Fill in the required information and send a post request with Volley. 填写所需信息,并向Volley发送发帖请求。 Then in the success block, parse your response to get access token, which you can use to retry calling blog API. 然后,在成功块中,解析您的响应以获取访问令牌,您可以使用该令牌重试调用博客API。

EDIT: See code snippet below. 编辑:请参见下面的代码段。 It is a rather mediocre code but it will be enough for the concept. 这是一个相当平庸的代码,但是对于这个概念来说已经足够了。 The point is that you refresh your access token with 401 error on blog API and then retry that API with the new access token from the response 关键是您在博客API上用401错误刷新访问令牌,然后使用响应中的新访问令牌重试该API。

RequestQueue queue;
String tokenUrl = "https://www.googleapis.com/oauth2/v4/token";
String blogUrl = "https://www.googleapis.com/blogger/v3/users/self/blogs";

public void onCreate() {
    queue = Volley.newRequestQueue(getApplicationContext());
    fetchBlogs("${your original access token here}");
}

void fetchBlogs(final @NonNull String accessToken) {
    JsonObjectRequest blogRequest = new JsonObjectRequest(Request.Method.GET, blogUrl, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            // successfully got blog response
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (error.networkResponse.statusCode == 401) {
                refreshAccessToken();
            } else {
                // irrecoverable errors. show error to user.
            }
        }
    }) {
        @Override
        public Map<String, String> getHeaders() {
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", "Bearer " + accessToken);
            return headers;
        }
    };
    queue.add(blogRequest);
}

void refreshAccessToken() {
    JSONObject params = new JSONObject();
    try {
        params.put("client_id", "${your client id here}");
        params.put("client_secret", "${your client secret here}");
        params.put("refresh_token", "${your refresh token here}");
        params.put("grant_type", "refresh_token");
    } catch (JSONException ignored) {
        // never thrown in this case
    }

    JsonObjectRequest refreshTokenRequest = new JsonObjectRequest(Request.Method.POST, tokenUrl, params, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                String accessToken = response.getString("access_token");
                fetchBlogs(accessToken);
            } catch (JSONException e) {
                // this will never happen but if so, show error to user.
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // show error to user. refresh failed.
            Log.e("Error on token refresh", new String(error.networkResponse.data));

        }
    });
    queue.add(refreshTokenRequest);
}

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

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