Validación del lado del servidor del token de acceso de Facebook para la aplicación de iPhone

112

Estoy desarrollando una aplicación para iPhone, que se basa en la comunicación con el servidor, y quiero utilizar los mecanismos de autenticación de Facebook.

Básicamente, creo que debería funcionar así:

  1. En la aplicación de mi iPhone, el usuario inicia sesión en Facebook con su correo electrónico y contraseña.
  2. El usuario permite el acceso a sus datos para la aplicación de Facebook relacionada.
  3. La aplicación de mi iPhone recibe el token de acceso después de iniciar sesión correctamente.
  4. En una mayor comunicación con mi servidor, mi aplicación de iPhone debe usar el token de acceso de Facebook recibido (por ejemplo: en consultas).
  5. Cuando mi servidor recibe alguna consulta de la aplicación de iPhone, con token de acceso, debe preguntarle a Facebook que este token es válido (y para quién), y si es así, el servidor debe asumir que el usuario está autenticado con Facebook.

Mi pregunta es: ¿cómo debe el servidor preguntarle a Facebook si el token de acceso dado es válido? Creo que de alguna manera debería verificar si el token es válido para mi aplicación de Facebook.

He probado muchas consultas de Facebook para graficar API, que he encontrado, pero nada funcionó como esperaba. ¿Me puede dar algún ejemplo?

Marcin
fuente
5
A menos que el usuario haya cerrado la sesión de la aplicación en FB, puede enviar el token de autenticación al servidor (ssl con suerte). ¿Tiene éxito o falla una simple consulta de "/ me" a través de la API de gráficos?
The Mad Gamer
recibirá un mensaje en respuesta de Facebook que su token no es válido :)
Jean-Luc Godard
1
Estoy intentando hacer algo muy similar a lo que estás haciendo. Nunca marcó esta pregunta como respondida, ¿alguna vez logró que esto funcionara?
Tempy
¿Qué sucede cuando expira el access_token? ¿Deberíamos pedirle al usuario que vuelva a iniciar sesión? Quiero entender cómo volver a validar nuevamente después de que el token
caduque
@debianmaster depende de la arquitectura de su aplicación. Si considera el caso "sin token FB - sin acceso a la aplicación", entonces sí, cierre la sesión del usuario. De lo contrario, podría considerar una lógica de "desvinculación", en la que el usuario permanece conectado, pero la información recibida de Facebook se desconecta de su cuenta en el servidor / cliente.
Yevhen Dubinin

Respuestas:

115

Aquí hay un proceso de dos pasos que puede utilizar para validar que un token de acceso de usuario pertenece a su aplicación:

1) Genere un token de acceso a la aplicación

( 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) Depurar el token de acceso de usuario

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

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

Donde INPUT_TOKEN es el token de acceso de usuario que desea verificar y ACCESS_TOKEN es el token de su aplicación que obtuvo en el paso 1.

El punto final de depuración básicamente descarga toda la información sobre un token, por lo que responderá con algo como esto:

{
    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 ese token no es de "su aplicación", devolverá una respuesta de error.

sebastian el cangrejo
fuente
13
Según Facebook , esta es la forma correcta de inspeccionar tokens. Sin embargo, la primera parte es opcional, ya que puede usar su ID de aplicación y su secreto en lugar de un administrador o un token de aplicación.
Brandon Zacharie
@BrandonZacharie No veo cómo haces esto, acabo de intentarlo con el ID de la aplicación y el secreto y me dio un error de "parámetro input_token requerido"
Johnny Z
@JohnnyZ se requiere el token de entrada. El token de acceso es donde está la flexibilidad.
Brandon Zacharie
8
@BrandonZacharie Tienes razón, estaba confundiendo las entradas y los tokens de acceso. Para usar la identificación y el secreto de la aplicación, pasé esto como un parámetro con una tubería como delimitador: & access_token = APP_ID | APP_SECRET
Johnny Z
2
El enlace de arriba ahora es developers.facebook.com/docs/facebook-login/access-tokens/…
Chris Prince
115

Actualización: esta respuesta parece insegura ya que no valida el token primero como perteneciente a su aplicación, vea los comentarios, la respuesta original es la siguiente:

Supongo que ya tiene el token de acceso en la mano. En tal caso, la forma más sencilla de validar un token de acceso es emitir la siguiente solicitud

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

Aquí reemplace @accesstoken con el token de acceso que tiene. Desglosaré la URL y explicaré cada una.

Estamos emitiendo una solicitud de API de gráfico aquí que devolverá el ID de usuario de Facebook del propietario del token de acceso como una cadena JSON. La palabra clave 'yo' representa al usuario actualmente conectado o al propietario del token de acceso. Para esta solicitud, el token de acceso es un parámetro obligatorio.

Si el token de acceso proporcionado no es válido o ha caducado, Facebook simplemente devolverá un mensaje de error de algún tipo.

Para un token de acceso válido, el resultado de alguna manera se verá así

{
   "id": "ID_VALUE"
}
Robin
fuente
14
¿No tendría éxito esa solicitud si ese usuario proporcionara un access_token que pertenece a una aplicación diferente?
Yuriy Nemtsov
2
Se puede usar cualquier token de acceso de usuario válido (sin importar a qué aplicación pertenezca)
Robin
12
@Xiquid esta publicación no es la solución al problema ya que no valida si el token de acceso pertenece a su aplicación.
Kolyunya
12
¡No entiendo por qué esta respuesta tiene la mayor cantidad de votos! OBVIAMENTE no es la solución correcta. En realidad, el enfoque correcto es lo que sugirió "el cangrejo sebastian". El punto final debug_token se usa para consultar información sobre el token en sí y de esta manera puede verificar que el token pertenece a un ID de usuario específico para un ID de aplicación específico.
Alex Ntousias
4
Sí, esta respuesta no es correcta. Si verifica el token de acceso de esta manera, alguien puede obtener un token de acceso de una aplicación diferente y usarlo para autenticarse con el suyo.
Jonathan
11

Otra solución sería usar https://graph.facebook.com/app/?access_token=[user_access_token]como se describe en Obtener la identificación de la aplicación del token de acceso del usuario (o verificar la aplicación de origen para un token) .

Esta parece ser una característica no documentada, pero devuelve JSON que contiene el ID de la aplicación para la que se generó el token. Si el token no era para su aplicación, devuelve 400.

Helen Williamson
fuente
¿Cómo puedo obtener las calificaciones de otros negocios de Facebook? ¿Qué necesito hacer para esto?
Maneesh Rao
6

En la última versión de facebook (2.2) puedes hacerlo de esta manera:

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

Salida de muestra:

{
    "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
fuente
¿Significa esto que tendrá que llamar a este punto final de fb en cada solicitud? ¿No hay una forma mejor?
Jdruwe
Esto funciona pero requiere el token de acceso. El token de acceso se puede generar usando la respuesta 'sebastian the crab' o simplemente podemos usar appid | appsecret. Para obtener más información developers.facebook.com/docs/facebook-login/…
krishnan
Aquí hay un ejemplo de uso de esto: 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");
}

Puede descargar el SDK de Facebook para PHP desde GitHub .

Baptiste Costa
fuente
1

Si un usuario te ha pasado un UID de Facebook que afirma que es suyo y quieres comprobar si es legítimo, esta es una función de Python que lo verificará con su token de acceso (una implementación de la respuesta 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
fuente
Esto no valida que el token se generó "para su aplicación" desafortunadamente ...
rogerdpack
1

Este es el único método seguro para verificar el token de usuario con solo una solicitud:

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

Tenga en cuenta que un signo "|" en la URL anterior no se usa como OR sino como separador y debe estar allí después de completar los otros campos.

La respuesta será JSON con el siguiente aspecto:

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

Referencia: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (el método anterior se menciona al final de esta sección)

Kamoris
fuente
Hay otra forma segura con una solicitud: stackoverflow.com/a/36555287/32453
rogerdpack
-1

Junto con un token de acceso, Facebook también envía un parámetro "expires_in", que es un valor de compensación. Úselo para calcular cuándo caducará el token de acceso como NSDate. Luego, cuando necesite hacer una solicitud, compare la fecha actual con la fecha de vencimiento.

También intente inspeccionar los códigos de estado y las cadenas de respuesta que envía Facebook.

jcm
fuente