14

Этот вопрос задан несколько раз в Stack, но реальных ответов не было. Позвольте мне попытаться объяснить мою ситуацию в любом случае.Facebook OAuth Login - access_token API возвращается «Этот код авторизации был использован»

Мы используем приложение, использующее логин Facebook OAuth2. Этот логин использовался, чтобы нормально работать до прошлой недели, и внезапно это беспокоит нас сейчас.

Flow Применение:

Шаг 1: прессы пользователя войти в систему с помощью кнопки Facebook на нашем сайте

Шаг 2: перенаправлено на Facebook страницу Войти/авторизации

Шаг 3 : При авторизации приложения обратный вызов поступает в наше приложение с кратковременным параметром «код».

Шаг 4: Этот параметр «код» будет заменен на токен доступа на 60 дней с использованием «https://graph.facebook.com/oauth/access_token».

Ошибка на шаге 4:

Когда мы пытаемся обменять короткую жизнь «код» для маркеров доступа, мы получаем эту ошибку от Facebook.

{"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}} 

Наблюдение:

  1. Для пользователей, которые вновь поступающих к приложению, вышеизложенная ошибка не возникает.
  2. Для возвращаемого пользователя этот вызов завершается с ошибкой выше.
  3. Наша заявка действует уже более 9 месяцев, и эта ошибка появилась только в последние 7-10 дней. До этого у нас было тысячи пользователей, которые успешно использовали его.

То, что я уже получил от форумов:

Вот моя интерпретация того, что я прочитал. Может быть неточным. У Facebook есть какая-то странная политика, которая требует, чтобы разработчик приложения поддерживал временный 10-минутный код, пока не истечет 60-дневный код, который был получен во время первого входа. Поэтому мы должны создать cookie с токеном доступа в браузере пользователя. Я даже мог видеть, как люди меняют свой код, чтобы создать куки.

Что меня беспокоит?

  1. Предлагаемые решения предполагают, что созданный файл cookie будет присутствовать в браузере пользователя всегда. Это плохое предположение, поскольку cookie может быть стерто в любое время.
  2. У меня есть другое приложение Id/app secret, которое я использую для своей разработки (например, localhost), и это отлично работает. Вход в систему происходит хорошо, но это единственный продукт, у которого есть проблема.
  3. Эта проблема не произошла на производственной машине в течение почти 10 месяцев с момента запуска приложения, и она внезапно появилась. Хуже всего, я не могу получить никаких записей о последних изменениях, которые нарушают этот поток.

Edit:

Платформа: Python, Google Appengine. Мы не используем никаких SDK для Facebook, мы делаем прямые HTTP-вызовы ко всем URL входа. Вызов: https://graph.facebook.com/oauth/access_token - мы передаем приложение, секрет и код (полученные из facebook) в течение 20 секунд после первого вызова.

Надеюсь, здесь достаточно информации, чтобы показать, что наш код не совсем неверен. Любые советы/указатели от людей, которые столкнулись и решили эту проблему, приветствуются. Если его ошибка в Facebook и Facebook-разработчик заметят, я буду еще счастливее.

+0

Параметр кода можно обменять только на токен доступа пользователя один раз. В вашем вопросе отсутствует какая-либо полезная информация о том, какую платформу/язык вы используете, и каковы ваши точные вызовы API. – CBroe

+0

@CBroe - Спасибо за уведомление. Да, мы понимаем, что параметр кода является одноразовым, и поэтому мы хотим обменять его на access_token, но URL-адрес токена доступа не работает. Я включил информацию о платформе/языке. – Srivatsan

ответ

0

Я тоже боролся с этим сегодня. Не уверен, что вы используете PHP-класс Facebook (из того, что вы написали, кажется, вы этого не сделали), однако это может быть указатель в любом случае - проблема в том, что библиотека PHP Facebook, похоже, получает токен из кода автоматически, и я пытался сделать это снова.

+0

У меня тоже была эта проблема. Он отлично работает, когда я вызываю шаг 4 выше (graph.facebook.com/oauth/access_token), прежде чем использовать PHP SDK для Facebook. Но если я позвоню ему, я получу «Этот код авторизации был использован». Токен, хранящийся в SDK, отличается от формата, возвращаемого конечной точкой, и я не видел даты истечения срока действия в SDK.Итак, если эти токены разные, почему Facebook возвращает ошибку в этом случае? –

4

Я обошел эту проблему, используя случайный GUID, который добавляется к каждому обратному URL-адресу, который я передаю в facebook. Кажется, код, который возвращает facebook, состоит из нескольких частей, включая параметр redirect_uri, который вы должны указать. Используя этот трюк GUID, ваше приложение продолжает работать, но facebook думает, что это другой URL-адрес, поэтому генерирует новый код.

Если вы храните этот GUID во временной сессии, это всегда одно и то же. Вот очень урезанная версия того, что я имею в виду. Я использую C#, но решение будет таким же:

Прежде чем начать процесс OAuth:

Session["facebook_buster"] = System.Guid.NewGuid().ToString(); 

Затем пнуть логин:

var facebook = new FacebookClient(); 

var loginUrl = facebook.GetLoginUrl(new 
{ 
    client_id = ..., 
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(), 
    display = "popup", 
    scope = "publish_stream,user_photos" 
}); 

А потом в моем обратном вызове метод, когда я хочу, чтобы обменять этот код для нового access_token:

var facebook = new FacebookClient(); 

dynamic result = facebook.Post("oauth/access_token", new 
{ 
    client_id = ..., 
    client_secret = ..., 
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(), 
    code = Request["code"] // this is the returned code from the first method 
}); 

Примечание в этом втором методе я USI g один и тот же ключ сеанса, чтобы код авторизации был успешным.

Проверено все это время, отменяя разрешения/вручную меняя мой сохраненный access_token (в моем db)/полностью удаляя мой сохраненный access_token, и он работает каждый раз.

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

+1

Нет сигары, https://github.com/HabitRPG/habitrpg/issues/4221#issuecomment-61855507 – lefnire

+0

Спасибо, сэр. На первый взгляд я не хотел, чтобы это работало. Но я реализовал его в PHP и вуаля! Долгосрочные токены доступа снова. Для новичков в этой проблеме Facebook должен использовать параметр 'redirect_uri' для генерации долгосрочного кода. По сути, мы используем алгоритм для создания уникальных долгосрочных кодов без прохождения 10 минут времени. Совершенно гениальный. –

+0

просто FYI, добавил параметр переадресации кэша к моему redirect_uri, когда получил URL-адрес входа в PHP, и получил тот же результат, что и я, предположим .. он сработал .. :) не могу поверить в эту ошибку с fb. Какой-то смешной? он говорил, что я уже использовал auth-коды, если бы я сохранил redirect_uri так же, как предыдущая попытка auth? действительно смущен, ну ладно. – jfaron

Смежные вопросы