Получить токен доступа из обновления токена в Volley - PullRequest
0 голосов
/ 28 декабря 2018

Я использую Android Volley для отправки HTTP-запроса на веб-сайт API блоггера, чтобы получить блог пользователя:

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

Я отправил запрос на залп на этот веб-сайтс HTTP Authorization header с bearer Access token, как сказано в документации:

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

Я отправил запрос следующим образом:

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);

Теперь все выглядит хорошо, но я вижу, чтотокен доступа меняется каждые 3599 секунд. Я хочу знать, чтобы программно обновить токен доступа, используя refresh token, предоставленный веб-сайтом OAuth Playground.

1 Ответ

0 голосов
/ 28 декабря 2018

Вы, вероятно, получили свой токен обновления, когда получили токен доступа.

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

Выше приведен пример ответа на запрос токена.Вы должны хранить этот токен обновления где-нибудь в безопасном месте, чтобы вы могли обновить свой токен доступа без другого процесса аутентификации через Google Login.

Не пытайтесь периодически обновлять свой токен доступа. Ваша логика должнане зависит от времени его истечения, потому что политика может измениться позже.

Просто попробуйте обновить его, когда вы фактически получаете ошибку 401 из любого ответа API.Поэтому я попытался бы обновить токен доступа при обнаружении кода состояния 401 http (который обычно означает, что токен истек) в методе onErrorResponse вашего запроса залпа.

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

В приведенной выше ссылке вы можете найти информацию о том, как обновить свой токен доступа.В разделе Обновление токена доступа показан пример запроса.

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

Введите необходимую информацию и отправьте запрос на публикацию с помощью Volley.Затем в блоке успеха проанализируйте свой ответ, чтобы получить токен доступа, который можно использовать для повторной попытки вызова API блога.

РЕДАКТИРОВАТЬ: см. Фрагмент кода ниже.Это довольно посредственный код, но этого будет достаточно для концепции.Дело в том, что вы обновляете свой токен доступа с ошибкой 401 в блоге API, а затем повторяете этот 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);
}
...