Facebook: обновить AccessToken на Android

В документе по AccessToken говорится следующее: "Родной мобильный приложения, использующие SDK Facebook, получат токены доступа с длительным сроком действия примерно на 60 дней. Эти токены будут обновляться один раз в день, когда человек, использующий ваше приложение, отправляет запрос на серверы Facebook."
Означает ли это, что только если запрос к серверам Facebook выполняется из клиентского приложения Android (я не уверен, как интерпретировать «... человек, использующий ваше приложение ...»), тогда токен доступа будет обновлен?
В моем приложении я получаю токен доступа с помощью AccessToken.getCurrentAccessToken(), отправьте токен доступа на мой сервер, и сервер сделает запрос к серверам Facebook с целью проверки полученного токена доступа.
Будет ли токен доступа обновлен в этом случае? (в этом случае сервер выполняет запрос к серверам FB, а не напрямую к «человеку, использующему мое приложение»)

  • Если да, то как Facebook SDK в клиентском приложении Android узнает, что мой сервер отправил запрос на серверы Facebook? Возвращает ли theAccessToken.getCurrentAccessToken() в Android-клиенте обновленный токен доступа?

Спасибо

EDIT: это может помочь другим сэкономить время: я обнаружил, что токен доступа при определенных условиях автоматически обновляется при инициализации FacebookSDK (документ Facebook не объясняет четко, как обновляется токен доступа — см. мой вопрос выше).
Обратите внимание, что я использую FacebookSDK 4.0 для Android.
Выполните следующие действия:

  1. FacebookSDK.sdkInitialize(Context, InitializeCallback)

    if (AccessToken.getCurrentAccessToken() != null && Profile.getCurrentProfile() == null)

  2. Profile.fetchProfileForCurrentAccessToken()

  3. Utility.getGraphMeRequestWithCacheAsync()

    GraphRequest graphRequest = getGraphMeRequestWithCache(accessToken); graphRequest.setCallback(graphCallback); graphRequest.executeAsync();

  4. ... executeBatchAsync(GraphRequestBatch requests)
    GraphRequestAsyncTask asyncTask = new GraphRequestAsyncTask(requests); asyncTask.executeOnSettingsExecutor();
  5. См. метод GraphRequestAsyncTask doInBackground()

if (connection == null) { return requests.executeAndWait(); } else { return GraphRequest.executeConnectionAndWait(connection, requests); }

В обоих случаях код окажется в этом методе:

public static List<GraphResponse> executeConnectionAndWait(
            HttpURLConnection connection,
            GraphRequestBatch requests)
  1. Обратите внимание на строку AccessTokenManager.getInstance().extendAccessTokenIfNeeded();. Что, как следует из названия, будет расширять ваш токен доступа не более одного раза в день.

comment
Да, в этом случае сервер отправляет запрос на обновление токена доступа и получит новый токен доступа. Однако приложение не будет знать об этом. Любые последующие запросы API будут по-прежнему выполняться со старым токеном доступа и завершатся ошибкой.   -  person subeeshb    schedule 16.07.2015
comment
@subeeshb Я не запрашиваю обновление токена доступа на сервере. Я просто вызываю /me .... запрос API GRAPH. Я думаю, вы не говорите, что каждый простой запрос API GRAPH включает в себя запрос на обновление токена доступа.   -  person FilipR    schedule 01.09.2015


Ответы (2)


Вы можете использовать метод refreshCurrentAccessTokenAsync:

AccessToken.refreshCurrentAccessTokenAsync();
person Pankaj Arora    schedule 18.12.2015
comment
Вот такой спаситель жизни :) - person Wahib Ul Haq; 25.02.2016
comment
Это только обновит дату истечения срока действия, если это возможно. Я проверил, что дата истечения срока действия может оставаться неизменной после вызова этой функции. Это потому, что теперь срок действия токена в любом случае истекает через 60 дней. Затем вам нужно снова попросить пользователя войти в систему через Facebook, чтобы обновить токен. - person crubio; 23.10.2018
comment
Но я не могу. Это не удалось при вызове. Ошибка: не удалось обновить токен доступа. Я использую тестового пользователя facebook. Пришлось сменить пароль и перелогиниться. Все еще не могу. - person Kyo Kurosagi; 26.02.2019
comment
Чувак, это было для старого SDK, FB сделал так много новых изменений в SDK. Я не уверен, что он будет работать и сегодня. - person Pankaj Arora; 27.02.2019
comment
Это не будет работать, если пользователь не вошел в систему через приложение facebook, потому что по какой-то причине они позволяют расширять только токены sso... Если пользователь вошел в систему через браузер, токен останется прежним. - person MarkoR; 29.03.2020

В документации говорится (выделено мной):

Когда вы используете SDK для iOS, Android или JavaScript, SDK автоматически обновляет токены, если человек использовал ваше приложение в течение последних 90 дней. Нативные мобильные приложения, использующие SDK Facebook, получают токены доступа пользователя с длительным сроком действия примерно 60 дней. Эти токены обновляются один раз в день, когда пользователь вашего приложения отправляет запрос на серверы Facebook.

Это означает, что если вы используете официальный встроенный в SDK клиент Graph API (GraphRequest и друзья), то после каждого запроса SDK будет попытаться обновить токен (но не чаще, чем один раз в день).

Для этого SDK использует недокументированный Graph API:

https://graph.facebook.com/v3.2/oauth/access_token?access_token={user-access-token}&grant_type=fb_extend_sso_token&client_id={your-app_id}

(Возможно, он доступен во всех версиях Graph API, но я его не тестировал)

Android SDK также предоставляет эту функцию обновления токена непосредственно в общедоступном API с помощью refreshCurrentAccessTokenAsync метод.

Очень важно отметить, что обновление токена работает только для так называемых токенов SSO, то есть полученных из приложения Facebook. Если на устройстве пользователя не установлено приложение Facebook или по какой-либо другой причине процесс входа использовал вариант веб-просмотра, токен, полученный таким образом, никогда не будет обновляться. Насколько я знаю, это нигде не задокументировано.

Упомянутый выше недокументированный API возвращает ошибку 400 при попытке обновить токен, полученный из потока веб-просмотра:

HTTP/1.1 400 Bad Request
...
{"error":{"message":"(#10) The access token was not obtained using single sign-on","type":"OAuthException","code":10,"fbtrace_id":"AbGFcwx4aOhY0sgEkLdAR34"}}

Весь этот ответ написан с учетом Android, но я предполагаю, что он применим и к iOS SDK (но я этого не проверял).

person cubuspl42    schedule 19.08.2020