Продлить токен авторизации без обновления страницы

Пользователи хотят использовать мое приложение facebook в течение многих часов, не обновляя браузер.
Но срок действия токена истекает через 2 часа. Теперь я прошу пользователей обновить страницу, но это раздражает.
Я не хочу запрашивать разрешения на автономный доступ, потому что это напугает некоторых пользователей.

Лучшим решением будет каким-то образом «перелогиниться» и получить новый токен, не обновляя страницу. Является ли это возможным?


person luchaninov    schedule 16.09.2011    source источник


Ответы (9)


Я бы подписался на триггер истечения срока действия (я думаю, что это authResponseChange), а затем автоматизировал бы еще одну проверку входа. Это не будет идеальным решением, поскольку оно может вызвать всплывающее окно (например, если они вышли из системы) автоматически, что может блокироваться многими браузерами. Вместо этого вы могли бы, когда срок действия токена истечет, проверить, нужно ли им завершить всплывающее окно, и отобразить уведомление на вашей странице где-нибудь с сообщением «Facebook требует вашего внимания, чтобы продолжить», а затем запустить всплывающее окно только из их ответа, что будет остановить блокировку всплывающего окна.

FB.Event.subscribe('auth.authResponseChange', function(response) {
  // do something with response
  FB.login(){
    // refresh their session - or use JS to display a notification they can 
    // click to prevent pop up issues
  }
});
person Abby    schedule 19.09.2011

Алгоритм тренировки на этом

  1. Запросить разрешение у пользователя
  2. Сохраните токен
  3. Периодически проверяйте срок действия токена доступа.
  4. Если срок действия истекает, вставьте какой-нибудь фиктивный iframe, который перенаправляет на домашнюю страницу facebook. - Продлить токен авторизации без обновления страницы
  5. Это должно обновить токен. Возможно, вам потребуется сгенерировать другой токен или продолжить с тем же. Все, что требуется, можно сделать без обновления страницы.
person acpmasquerade    schedule 25.09.2011
comment
На самом деле я обратился к фиктивной идее iframe в своем ответе. Это не сработает, потому что Facebook специально проверяет это и предотвращает. Ваши шаги 1-3 верны, но вместо шага 4 вы должны сделать редирект верхнего уровня. Затем новый токен будет доступен, и приложение сможет перейти оттуда. - person Floyd Wilburn; 26.09.2011

Вы думали об использовании ajax? Через два часа вы проверите, активен ли пользователь. Если это так, вы отправляете запрос axax на URL-адрес, где будут обновлены данные его сеанса. пример:

$(document).ready(function(){
    setInterval('update_session()', 5500000);
})
update_session(){
    $.post({
        URL: ..., // script to update session on server
        data:{ /* username, password */ },
    })
}

а серверная сторона просто берет имя пользователя и пароль из сообщения или запускает повторный вход.

person erazerhead    schedule 16.09.2011
comment
Но как я могу обновить сеанс на сервере? Насколько я понимаю, единственный способ обновить сеанс - перезагрузить всю страницу. - person luchaninov; 17.09.2011
comment
Должен сказать, что я действительно не знаю, как работают приложения facebook и что вообще можно сделать. Но обычно сеанс идентифицируется некоторым уникальным идентификатором сеанса, обычно хранящимся в файле cookie. И каждый раз, когда запрос отправляется на сервер, вместе с ним отправляется файл cookie. Затем сервер смотрит (обычно в кэш или в файл), зарегистрирован ли идентификатор сеанса - если да, то этому идентификатору присвоены данные пользователя. Таким образом, может быть две причины истечения срока действия сеанса - срок действия файла cookie истекает или сервер очищает свой реестр сеансов. Во-первых, я рекомендую попробовать периодически продлевать срок действия cookie (с помощью javascript). - person erazerhead; 17.09.2011
comment
Если это не сработает, вам придется отправить ajax-запрос с данными пользователя (имя пользователя, пароль) на какой-либо скрипт на стороне сервера, который выполнит повторный вход в систему и обновит идентификатор сеанса cookie. Вот и все. Вы делаете это и входите в систему. Или, может быть, вы могли бы попытаться изменить время сеанса на стороне сервера, но, как я уже говорил, я понятия не имею, как происходит программирование на Facebook и какие привилегии есть у пользователей. - person erazerhead; 17.09.2011
comment
Сам PHP не может войти в систему, поэтому я не могу использовать его для продления сеанса. Вместо этого PHP может получить URL-адрес, по которому я направлю пользователя для подтверждения. И это означает обновление страницы, которого я стараюсь избегать. - person luchaninov; 19.09.2011
comment
Я думаю, что вы получите большую пощечину, если спросите их имя пользователя и пароль на Facebook. - person Abby; 19.09.2011
comment
Если у вас есть вариант использования, который требует доступа к access_tokens с медленным сроком действия, просто попросите разрешение offline_access, это в основном то, для чего оно нужно. - person Igy; 21.09.2011

Попробуйте получить токены с разрешением offline_access.

person chwk    schedule 21.09.2011
comment
Я не могу. Я теряю меньше пользователей из-за этой ошибки, чем когда добавляю это разрешение, и пользователи не нажимают «Принять». - person luchaninov; 22.09.2011

Я предполагаю, что это невозможно, архитектура FB не позволит этого. И почему offline_access такая проблема!!!!!!!...в любом случае offline_access - лучшее оптимальное решение, я думаю....

person Dilip.m    schedule 23.09.2011
comment
Область offline_access скоро будет устаревшей, как вы можете видеть здесь: developers.facebook.com/ docs/offline-access-deprecation . Было бы разумно принять это во внимание, если вы разрабатываете приложение прямо сейчас. - person Marc Hoogvliet; 27.01.2012

К сожалению, я считаю, что это невозможно по дизайну (если вы хотите, чтобы это произошло без вмешательства пользователя). Если пользователь все еще вошел в систему Facebook, вы можете перенаправить страницу верхнего уровня на Facebook, и она сразу же вернет вас с новым кодом (похоже, вы уже делаете это), но это возможно только из-за Facebook. cookie, который он может проверить. Если вы попытаетесь сделать что-либо со своего сервера, оно будет отклонено, поскольку этот файл cookie не будет сопровождать запрос. То же самое касается попытки позвонить в facebook из javascript — поскольку ваш код работает в другом домене, файл cookie не будет сопровождать вызов, и Facebook отклонит его. Единственный способ, с помощью которого Facebook может узнать, кто такой пользователь и что он все еще вошел в систему, — это увидеть этот файл cookie. И единственный способ, которым это может произойти, — это если сам браузер будет перенаправлен на домен facebook.com.

Стоит также упомянуть, что Facebook заблокировал единственный логический обходной путь, то есть загрузку URL-адреса oauth в iframe. Если вы попробуете, вы увидите, что они обнаруживают, что страница загружается в iframe, и выводят страницу со ссылкой на нее, которая выполняет перенаправление верхнего уровня для выхода из фрейма. Таким образом, этот подход не только не работает, ясно, что Facebook специально сделал это невозможным как часть своей архитектуры.

Изменить: если вы хотите не полностью избегать обновления, а просто сделать так, чтобы оно происходило автоматически, когда требуется новый токен, вы можете сделать что-то вроде этого:

$status=0;
$data=@file_get_contents("https://graph.facebook.com/me?access_token=$token");
foreach ($http_response_header as $rh) if (substr($rh, 0, 4)=='HTTP') list(,$status,)=explode(' ', $rh, 3);
if ($status==200)
  {
  //token is good, proceed
  }
else
  {
  //token is expired, get new one
  $fburl="http://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=".urlencode('http://apps.facebook.com/yourapp/thispage.php');
  echo "<html>\n<body>\n<script>top.location='$fburl';</script>\n</body>\n</html>\n";
  exit;
  }

Предполагается, что перед этим кодом у вас есть что-то, что обработает параметр signed_request, если он присутствует, и присвоит значение $token (либо ваш собственный явный код, либо соответствующие записи SDK). Затем показанный код можно использовать везде, где вам нужно проверить, действителен ли $token, прежде чем продолжить.

person Floyd Wilburn    schedule 19.09.2011
comment
Но вы можете открыть какую-нибудь игру утром, принять какие-то подарки вечером и они тут же удалятся из ваших уведомлений. Таким образом, они каким-то образом продлевают токены доступа и не заставляют меня обновляться. Я хочу сделать то же самое в своем приложении. - person luchaninov; 19.09.2011
comment
Возможно, я не совсем понимаю, что вы пытаетесь сделать. Я думал, вы имели в виду, что ваши пользователи будут взаимодействовать только с холстом вашего приложения, и поэтому у вас будет только исходный токен, который вы получили, когда они впервые открыли его, срок действия которого истекает через два часа. Похоже, теперь вы описываете пользователя, который возвращается в ваше приложение, взаимодействуя с фреймом Facebook? - person Floyd Wilburn; 19.09.2011
comment
Я хочу, чтобы пользователь, зашедший 10 часов назад и не обновивший браузер, мог отправлять подарки своим друзьям. Но как это возможно в других играх Facebook, если срок действия токена истекает через 2 часа? - person luchaninov; 19.09.2011
comment
Когда вы говорите, что браузер не обновлялся, вы имеете в виду, что пользователь ничего не делал вручную (например, фактически не нажимал кнопку обновления)? Или что вы не хотите, чтобы ваше приложение полностью обновляло страницу? Опять же, я думаю, что я, должно быть, не понимаю, чего вы действительно хотите, я думал, вы говорите, что хотите обновить токен, но не выполняя перенаправление верхнего уровня. Давайте перефразируем: в вашей текущей настройке, что происходит, когда срок действия токена истекает, и что должно произойти вместо этого? - person Floyd Wilburn; 19.09.2011
comment
Игрок входит в игру, нажимает какие-то кнопки. Идет где-то часа 3, браузер остается открытым. Затем он нажимает «Принять подарок», сервер пытается удалить уведомление от Facebook, но Facebook сообщает, что срок действия токена истек. Другие игры каким-то образом умудряются убирать уведомления. - person luchaninov; 20.09.2011

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

person mjs    schedule 22.09.2011
comment
то есть если offline_access находится в области во время создания токена доступа, он не хочет использовать эту область, поэтому срок действия токена доступа истекает. - person Dilip.m; 23.09.2011

Я предполагаю, что вы используете параметр iframe signed_request для получения токена доступа. Одним из способов достижения того, что вам нужно, является использование метода oAuth 2.0 для получения токена доступа. В первом случае это более продолжительно; ваш сервер и Facebook должны обмениваться учетными данными, что может быть медленным, но это означает, что вам будет предоставлен code, который можно регулярно обменивать на токен доступа, что означает, что ваш сервер может периодически поддерживать сеанс (вероятно, из-за вызова ajax от клиента ). Затем вы должны передать этот новый access_token клиенту и использовать его в своем диалоговом вызове для ваших запросов (подарков).

Надеюсь, это поможет.

Спэбби

person GeeH    schedule 22.09.2011
comment
Спасибо. Я скоро перейду на oAuth 2.0 и проверю, помогает ли это. - person luchaninov; 22.09.2011
comment
Хотя я никогда не проверял это, согласно документации, вы не можете продолжать использовать один и тот же код для получения новых токенов. Если вам нужно получить новый код, вы снова в той же лодке. - person Floyd Wilburn; 22.09.2011

Взгляните на https://developers.facebook.com/docs/offline-access-deprecation/#extend_token

в основном вы расширяете токен с помощью

https://graph.facebook.com/oauth/access_token?             
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN 

это даст вам новый токен с новым сроком действия (должно быть 60 дней, но я заметил похожую ошибку, описанную здесь https://developers.facebook.com/bugs/347831145255847/?browse=search_4f5b6e51b18170786854060 )

person equivalent8    schedule 12.03.2012