Проверка токена доступа Facebook на стороне сервера для приложения iPhone


112

Я разрабатываю приложение для iPhone, которое основано на связи с сервером, и я хочу использовать механизмы аутентификации Facebook.

В принципе, я думаю, это должно работать так:

  1. В моем приложении для iPhone пользователь входит в Facebook, используя свой адрес электронной почты и пароль.
  2. Пользователь разрешает доступ к своим данным для соответствующего приложения Facebook.
  3. Мое приложение для iPhone получает токен доступа после успешного входа в систему.
  4. В дальнейшем общении с моим сервером мое приложение iPhone должно использовать полученный токен доступа Facebook (например, в запросах).
  5. Когда мой сервер получает некоторый запрос из приложения iPhone с токеном доступа, он должен спросить Facebook, действителен ли этот токен (и для кого), и если да, сервер должен предположить, что пользователь аутентифицирован с помощью Facebook.

Мой вопрос: как сервер должен спрашивать Facebook, действителен ли данный токен доступа? Я думаю, мне нужно как-то проверить, действителен ли токен для моего приложения Facebook.

Я пробовал много запросов Facebook для графического API, которые я нашел, но ничего не сработало, как я ожидал. Вы можете привести мне пример?


5
Если пользователь не вышел из приложения в FB, вы можете просто отправить токен аутентификации на сервер (ssl hopefuly). Выполняется ли простой запрос "/ me" через api графа успешно или нет?
— The Mad Gamer

в ответ вы получите сообщение от facebook, что ваш токен недействителен :)
— Жан-Люк Годар,

1
Я пытаюсь сделать что-то очень похожее на то, что делаете вы. Вы никогда не отмечали этот вопрос как ответ, у вас когда-нибудь это работало?
— tempy

Что произойдет, когда истечет срок действия access_token? мы должны попросить пользователя снова войти в систему? я хочу понять, как повторно выполнить проверку после истечения срока действия токена
— debianmaster

@debianmaster это зависит от архитектуры вашего приложения. Если вы рассматриваете случай «нет токена FB - нет доступа к приложению», то да, выйдите из системы. В противном случае вы можете рассмотреть логику «отсоединения», при которой пользователь остается в системе, но информация, полученная от Facebook, отключается от его учетной записи на сервере / клиенте.
— Евгений Дубинин

Ответы:


115

Вот двухэтапный процесс, который вы можете использовать для проверки принадлежности токена доступа к вашему приложению:

1) Создайте токен доступа к приложению

( https://developers.facebook.com/docs/howtos/login/login-as-app/ )

https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials

2) Отладка токена доступа пользователя

( https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/ )

https://graph.facebook.com/debug_token?
input_token=INPUT_TOKEN
&access_token=ACCESS_TOKEN

Где INPUT_TOKEN - это токен доступа пользователя, который вы хотите проверить, а ACCESS_TOKEN - это токен вашего приложения, который вы получили на шаге 1.

Конечная точка отладки в основном сбрасывает всю информацию о токене, поэтому она ответит примерно так:

{
    data: {
        app_id: YOUR_APP_ID,
        is_valid: true,
        metadata: {
            sso: "iphone-safari"
        },
        application: YOUR_APP_NAMESPACE,
        user_id: USER_ID,
        issued_at: 1366236791,
        expires_at: 1371420791,
        scopes: [ ]
    }
}

Если этот токен не из «вашего приложения», он вернет ответ с ошибкой.


13
Согласно Facebook , это правильный способ проверки токенов. Однако первая часть является необязательной, поскольку вы можете использовать свой идентификатор и секрет приложения вместо токена администратора или приложения.
— Брэндон Захари

@BrandonZacharie Не понимаю, как вы это делаете, я просто попробовал с идентификатором и секретом приложения и дал мне ошибку «Требуется параметр input_token»
— Johnny Z

@JohnnyZ требуется входной токен. Токен доступа - вот где гибкость.
— Brandon Zacharie

8
@BrandonZacharie Вы правы, меня путали токены ввода и доступа. Чтобы использовать идентификатор и секрет приложения, я передал это как параметр с вертикальной чертой в качестве разделителя: & access_token = APP_ID | APP_SECRET
— Johnny Z


115

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

Я предполагаю, что у вас уже есть токен доступа. В таком случае самый простой способ проверить токен доступа - выполнить следующий запрос

https://graph.facebook.com/me?fields=id&access_token=@accesstoken

Здесь замените @accesstoken на имеющийся у вас токен доступа. Я разобью URL-адрес и объясню каждый.

Здесь мы отправляем запрос api графика, который вернет идентификатор пользователя Facebook владельца токена доступа в виде строки JSON. Ключевое слово «я» представляет вошедшего в систему пользователя или владельца токена доступа. Для этого запроса токен доступа является обязательным параметром.

Если предоставленный токен доступа недействителен или просрочен, Facebook просто вернет какое-то сообщение об ошибке.

Для действующего токена доступа результат будет как-то выглядеть так

{
   "id": "ID_VALUE"
}

14
Разве этот запрос не будет успешным, если этот пользователь предоставит access_token, который принадлежит другому приложению?
— Юрий Немцов

2
Можно использовать любой действительный токен доступа пользователя (независимо от того, к какому приложению он принадлежит)
— Робин,

12
@Xiquid этот пост не является решением проблемы, поскольку он не проверяет, принадлежит ли токен доступа вашему приложению.
— Колюня

12
Я не понимаю, почему у этого ответа больше всего голосов! Это ЯВНО неправильное решение. Собственно, правильный подход подсказал «краб Себастьян». Конечная точка debug_token используется для запроса информации о самом токене, и таким образом вы можете проверить, принадлежит ли токен определенному идентификатору пользователя для определенного идентификатора приложения!
— Alex Ntousias 01

4
Да, это неверный ответ. Если вы проверите токен доступа таким образом, кто-то сможет получить токен доступа из другого приложения и использовать его для аутентификации с вашим.
— Джонатан

11

Другое решение - использовать, https://graph.facebook.com/app/?access_token=[user_access_token]как описано в разделе Получить идентификатор приложения из токена доступа пользователя (или проверить исходное приложение для токена) .

Это похоже на недокументированную функцию, но возвращает JSON, содержащий идентификатор приложения, для которого был создан токен. Если токен не был для вашего приложения, он возвращает 400.


Как я могу получить рейтинги других компаний на Facebook. Что мне для этого нужно сделать?
— Маниш Рао,

6

В последней версии facebook (2.2) это можно сделать так:

https://developers.facebook.com/docs/graph-api/reference/v2.2/debug_token

Пример вывода:

{
    "data": {
        "app_id": "THE APP ID", 
        "application": "APP NAME", 
        "expires_at": 1427245200, 
        "is_valid": true, 
        "scopes": [
        "public_profile", 
        "basic_info", 
        "read_stream", 
        "email", 
        "publish_actions", 
        "read_friendlists", 
        "user_birthday", 
        "user_hometown", 
        "user_location", 
        "user_likes", 
        "user_photos", 
        "user_videos", 
        "user_friends", 
        "user_posts"
        ], 
        "user_id": "THE USER ID"
    }
}

Означает ли это, что вам придется вызывать эту конечную точку fb при каждом запросе? Нет лучшего способа?
— Jdruwe 08

Это работает, но для этого требуется токен доступа. Токен доступа можно сгенерировать с помощью ответа «краб Себастьян» или просто использовать appid | appsecret. Дополнительная информация developers.facebook.com/docs/facebook-login/…
— krishnan

Вот пример использования этого: stackoverflow.com/a/16947027/32453
— rogerdpack

2
private function facebookRequestMe($access_token)
{
    include_once "facebook.php";

    $facebook = new Facebook(array(
        "appId" => "your_application_id",
        "secret" => "your_application_secret"
    ));
    $facebook->setAccessToken($access_token);
    return $facebook->api("/me", "GET");
}

Вы можете скачать Facebook SDK для PHP с GitHub .


1

Если пользователь передал вам UID Facebook, который, по их утверждению, принадлежит им, и вы хотите проверить, является ли он законным, это функция Python, которая проверит его по их токену доступа (реализация ответа Робина Джома):

def verify_facebook_id(id, access_token):
    import requests
    import simplejson
    params = {'fields': 'id', 'access_token': access_token}
    text = requests.get("https://graph.facebook.com/me", params=params).text
    json = simplejson.loads(text)
    response_id = json["id"]
    return response_id == id

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

1

Это единственный безопасный метод проверки токена пользователя с помощью всего одного запроса:

https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app_id}|{app_secret}

Обратите внимание, что знак "|" в приведенном выше URL-адресе используется не как ИЛИ, а как разделитель и должен быть там после заполнения других полей.

Ответ будет в формате JSON следующего вида:

{
    data: {
        app_id: {app_id},
        application: {app_name},
        expires_at: {some_number},
        is_valid: {true|false}
        scopes: {array_of_permissions},
        user_id: {user_id}
    }
}

Ссылка: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (указанный выше метод упомянут в нижней части этого раздела)


Есть еще один безопасный способ с одним запросом: stackoverflow.com/a/36555287/32453
— rogerdpack

-1

Наряду с токеном доступа Facebook также отправляет параметр expires_in, который является значением смещения. Используйте это, чтобы вычислить, когда истечет срок действия токена доступа как NSDate. Затем, когда вам нужно сделать запрос, сравните текущую дату с датой истечения срока действия.

Также попробуйте проверить коды состояния и строки ответа, которые Facebook отправляет обратно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.