Validation côté serveur du jeton d'accès Facebook pour l'application iPhone

112

Je développe une application iPhone, basée sur la communication avec le serveur, et je souhaite utiliser les mécanismes d'authentification Facebook.

Fondamentalement, je pense que cela devrait fonctionner comme ceci:

  1. Dans mon application iPhone, l'utilisateur se connecte à Facebook, en utilisant son email et son mot de passe.
  2. L'utilisateur autorise l'accès à ses données pour l'application Facebook associée.
  3. Mon application iPhone reçoit un jeton d'accès après une connexion réussie.
  4. Lors de la communication avec mon serveur, mon application iPhone doit utiliser le jeton d'accès Facebook reçu (par exemple: dans les requêtes).
  5. Lorsque mon serveur reçoit une requête de l'application iPhone, avec un jeton d'accès, il doit demander à Facebook que ce jeton est valide (et pour qui), et si oui, le serveur doit supposer que l'utilisateur est authentifié avec Facebook.

Ma question est la suivante: comment le serveur doit-il demander à Facebook si le jeton d'accès donné est valide? Je pense que je devrais en quelque sorte vérifier si le jeton est valide pour mon application Facebook.

J'ai essayé de nombreuses requêtes Facebook pour grapher l'API, que j'ai trouvées, mais rien n'a fonctionné comme prévu. Pouvez-vous me donner un exemple?

Marcin
la source
5
À moins que l'utilisateur ne se soit déconnecté de l'application dans FB, vous pouvez simplement envoyer le jeton d'authentification au serveur (ssl, espérons-le). Une simple requête "/ me" via l'API graphique réussit-elle ou échoue-t-elle?
The Mad Gamer
vous recevrez un message de Facebook indiquant que votre jeton n'est pas valide :)
Jean-Luc Godard
1
J'essaie de faire quelque chose de très similaire à ce que vous faites. Vous n'avez jamais marqué cette question comme étant une réponse, avez-vous déjà fait fonctionner cela?
tempy
Que se passe-t-il lorsque le access_token expire? devrions-nous demander à l'utilisateur de se connecter à nouveau? Je veux comprendre comment valider à nouveau après l'expiration du jeton
debianmaster
@debianmaster cela dépend de l'architecture de votre application. Si vous considérez le cas "pas de jeton FB - pas d'accès à l'application", alors oui, déconnectez l'utilisateur. Sinon, vous pouvez envisager une logique de «dissociation», dans laquelle l'utilisateur reste connecté, mais les informations reçues de Facebook sont détachées de son compte sur le serveur / client.
Yevhen Dubinin

Réponses:

115

Voici un processus en deux étapes que vous pouvez utiliser pour valider qu'un jeton d'accès utilisateur appartient à votre application:

1) Générer un jeton d'accès aux applications

( 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) Déboguer le jeton d'accès utilisateur

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

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

Où INPUT_TOKEN est le jeton d'accès utilisateur que vous souhaitez vérifier, et ACCESS_TOKEN est le jeton de votre application que vous avez obtenu à l'étape 1.

Le point de terminaison de débogage vide essentiellement toutes les informations sur un jeton, donc il répondra avec quelque chose comme ceci:

{
    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: [ ]
    }
}

Si ce jeton ne provient pas de "votre application", il renverra une réponse d'erreur.

Sébastien le crabe
la source
13
Selon Facebook , c'est la bonne façon d'inspecter les jetons. Cependant, la première partie est facultative puisque vous pouvez utiliser votre identifiant et votre secret d'application au lieu d'un jeton d'administrateur ou d'application.
Brandon Zacharie
@BrandonZacharie Je ne vois pas comment vous faites cela, je viens d'essayer avec l'identifiant de l'application et le secret et m'a donné une erreur pour "paramètre input_token requis"
Johnny Z
@JohnnyZ le jeton d'entrée est requis. Le jeton d'accès est l'endroit où se trouve la flexibilité.
Brandon Zacharie
8
@BrandonZacharie Vous avez raison, j'obtenais des jetons d'entrée et d'accès confus. Pour utiliser l'identifiant et le secret de l'application, j'ai passé ceci en paramètre avec un tube comme délimiteur: & access_token = APP_ID | APP_SECRET
Johnny Z
2
Le lien ci-dessus est maintenant developer.facebook.com/docs/facebook-login/access-tokens/…
Chris Prince
115

Mise à jour: cette réponse semble peu sécurisée car elle ne valide pas le jeton en premier comme appartenant à votre application, voir les commentaires, réponse originale comme suit:

Je suppose que vous avez déjà le jeton d'accès en main. Dans un tel cas, le moyen le plus simple de valider un jeton d'accès est d'émettre la requête suivante

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

Remplacez ici @accesstoken par le jeton d'accès dont vous disposez. Je décomposerai l'url et expliquerai chacun.

Nous émettons ici une demande d'API graphique qui renverra l'ID utilisateur Facebook du propriétaire du jeton d'accès sous forme de chaîne JSON. Le mot-clé «moi» représente l'utilisateur actuellement connecté ou le propriétaire du jeton d'accès. Pour cette demande, le jeton d'accès est un paramètre obligatoire.

Si le jeton d'accès fourni n'est pas valide ou a expiré, Facebook renverra simplement un message d'erreur quelconque.

Pour un jeton d'accès valide, le résultat ressemblera en quelque sorte à ceci

{
   "id": "ID_VALUE"
}
Robin
la source
14
Cette demande ne réussirait-elle pas si cet utilisateur fournissait un access_token qui appartient à une autre application?
Yuriy Nemtsov
2
Tout jeton d'accès utilisateur valide peut être utilisé (quelle que soit l'application à laquelle il appartient)
Robin
12
@Xiquid ce post n'est pas la solution au problème car il ne valide pas si le jeton d'accès appartient à votre application.
Kolyunya
12
Je ne comprends pas pourquoi cette réponse a le plus de votes! Ce n'est évidemment pas la bonne solution. En fait, la bonne approche est celle que suggérait «Sébastien le crabe». Le point de terminaison debug_token est utilisé pour demander des informations sur le jeton lui-même et de cette façon, vous pouvez vérifier que le jeton appartient à un ID utilisateur spécifique pour un ID d'application spécifique!
Alex Ntousias
4
Ouais, cette réponse n'est pas correcte. Si vous vérifiez le jeton d'accès de cette manière, quelqu'un peut obtenir un jeton d'accès d'une autre application et l'utiliser pour s'authentifier auprès de la vôtre.
Jonathan
11

Une autre solution consisterait à utiliser https://graph.facebook.com/app/?access_token=[user_access_token]comme décrit par Obtenir l'ID d'application à partir du jeton d'accès utilisateur (ou vérifier l'application source pour un jeton) .

Cela semble être une fonctionnalité non documentée, mais renvoie JSON contenant l'ID de l'application pour laquelle le jeton a été généré. Si le jeton n'était pas pour votre application, il renvoie un 400.

Helen Williamson
la source
Comment puis-je obtenir les évaluations d'autres entreprises Facebook. Que dois-je faire pour cela?
Maneesh Rao le
6

Dans la dernière version de facebook (2.2), vous pouvez le faire de cette façon:

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

Exemple de sortie:

{
    "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"
    }
}
Shoeb Ahmed Mogal
la source
Cela signifie-t-il que vous devrez appeler ce point de terminaison fb à chaque demande? N'y a-t-il pas un meilleur moyen?
Jdruwe
Cela fonctionne mais cela nécessite le jeton d'accès. Le jeton d'accès peut être généré en utilisant la réponse `` sebastian le crabe '' ou nous pouvons simplement utiliser appid | appsecret. Pour plus d'informations developer.facebook.com/docs/facebook-login/…
krishnan
Voici un exemple d'utilisation de ceci: 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");
}

Vous pouvez télécharger le SDK Facebook pour PHP depuis GitHub .

Baptiste Costa
la source
1

Si un utilisateur vous a transmis un UID Facebook qu'il prétend être le sien et que vous souhaitez vérifier s'il est légitime, il s'agit d'une fonction Python qui le vérifiera par rapport à son jeton d'accès (une implémentation de la réponse de Robin Jome):

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
Andrew Magee
la source
Cela ne valide pas que le jeton a été généré "pour votre application" malheureusement ...
rogerdpack
1

C'est la seule méthode sécurisée pour vérifier le jeton utilisateur en utilisant une seule demande:

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

Notez qu'un signe "|" dans l'URL ci-dessus n'est pas utilisé comme OU mais comme séparateur et doit être là après avoir rempli les autres champs.

La réponse sera JSON ressemblant à ça:

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

Référence: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (la méthode ci-dessus est mentionnée au bas de cette section)

Kamoris
la source
Il existe un autre moyen sécurisé avec une seule demande: stackoverflow.com/a/36555287/32453
rogerdpack
-1

En plus d'un jeton d'accès, Facebook envoie également un paramètre "expires_in", qui est une valeur de décalage. Utilisez-le pour calculer le moment où le jeton d'accès expirera en tant que NSDate. Ensuite, lorsque vous avez besoin de faire une demande, comparez la date actuelle avec la date d'expiration.

Essayez également d'inspecter les codes d'état et les chaînes de réponse que Facebook renvoie.

jcm
la source