Проверка токена доступа 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.