tools page obtener developers app facebook security authentication facebook-access-token facebook-authentication

page - ¿Cómo debe consumirse un token de acceso de usuario de Facebook en el lado del servidor?



obtener access token facebook (2)

  1. No veo ninguna brecha evidente, pero no soy un experto en seguridad.
  2. Una vez que su servidor haya verificado el token dado (paso 8), como usted dijo:

La respuesta aceptada en esta pregunta de StackOverflow recomienda crear un token de acceso personalizado después de que se complete la primera verificación del token de usuario de Facebook. El token personalizado se enviará al cliente para solicitudes posteriores. Me pregunto si esto es más complejo que la solución anterior, sin embargo. Esto requeriría la implementación de mi propio Proveedor de Identidad (algo que quiero evitar porque, en primer lugar, quiero usar proveedores externos de identidades ...). ¿Hay algún mérito en esta sugerencia?

En mi humilde opinión es el camino a seguir. Utilizaría https://jwt.io/ que le permite codificar valores (el ID de usuario, por ejemplo) usando una clave secreta. Luego, su cliente adjuntará este token a cada solicitud. De modo que puede verificar la solicitud sin necesidad de un tercero (tampoco necesita consultas de bases de datos). Lo bueno aquí es que no hay necesidad de almacenar el token en su base de datos.

Puede definir una fecha de caducidad en el token, para obligar al cliente a autenticarse con el tercero nuevamente cuando lo desee.

  1. Digamos que quiere que su servidor pueda hacer algo sin la interacción del cliente. Por ejemplo: abrir historias gráficas . En este escenario, porque necesita publicar algo en nombre del usuario, necesitaría el token de acceso almacenado en su base de datos.

(No puedo ayudar con las 3 y 4 preguntas, lo siento).

Prefacio

Estoy desarrollando varios servicios web y un puñado de clientes (aplicación web, dispositivos móviles, etc.) que interactuarán con dichos servicios a través de HTTP (s). Mi trabajo actual es diseñar una solución de autenticación y autorización para el producto. He decidido aprovechar los proveedores externos de identidad, como Facebook, Google, Microsoft, Twitter y similares para la autenticación.

Estoy tratando de resolver el problema de "cuando recibo una solicitud en mi servidor, ¿cómo sé quién es el usuario y cómo puedo estar seguro?". Más preguntas a continuación también ...

Requisitos

  1. Confíe en las identidades externas para indicar con quién estoy tratando (''userId'' esencialmente es todo lo que me importa).
  2. El sistema debe usar autenticación basada en token (a diferencia de las cookies, por ejemplo, o autenticación básica).

    Creo que esta es la opción correcta para escalar a través de múltiples clientes y servidores, a la vez que proporciona un acoplamiento flexible.

Flujo de trabajo

Según mi lectura y comprensión de la autenticación basada en tokens, la siguiente es cómo me imagino que será el flujo de trabajo. Centrémonos por ahora en Facebook en un navegador web . Mi suposición es que otros proveedores de identidad externa deberían tener capacidades similares, aunque todavía no lo he confirmado.

Tenga en cuenta que, al momento de escribir, estoy basando lo siguiente en la versión de inicio de sesión de Facebook 2.2

  1. Cliente: inicia el inicio de sesión en Facebook con el JavaScript SDK
  2. Facebook: el usuario autentica y aprueba los permisos de la aplicación (para acceder al perfil público del usuario, por ejemplo)
  3. Facebook: envía una respuesta al cliente que contiene un token de acceso del usuario, una identificación y una solicitud firmada
  4. Cliente: Almacena el token de acceso de usuario en la sesión del navegador ( manejado por SDK convenientemente )
  5. Cliente: realiza una solicitud a mi servicio web para obtener un recurso seguro al enviar el token de acceso del usuario en el encabezado de autorización + la ID del usuario (en el encabezado personalizado)
  6. Servidor: lee el token de acceso de usuario del encabezado de solicitud e inicia la verificación enviando una solicitud a la API de gráfico debug_token proporcionada por Facebook
  7. Facebook: Responde al servidor con la información del token de acceso del usuario (contiene appId y userId)
  8. Servidor: completa la verificación del token comparando la aplicación con lo que se espera (conocido por sí mismo) y el ID del usuario con lo que se envió a petición del cliente
  9. Servidor: Responde al cliente con el recurso solicitado (asumiendo la feliz ruta de autorización)

Me imagino que los pasos 5 a 9 se repetirán para solicitudes posteriores al servidor (mientras que el token de acceso del usuario es válido, no caducado, revocado desde el lado FB, los permisos de la aplicación han cambiado, etc.)

Aquí hay un diagrama para ayudar a seguir los pasos. Comprenda que este sistema no es una aplicación de una sola página (SPA). Los servicios web mencionados son puntos finales API que sirven datos JSON a los clientes esencialmente; no están sirviendo HTML / JS / CSS (con la excepción de los servidores de cliente web).

Preguntas

  1. Primero y ante todo, ¿hay algunas lagunas evidentes / caídas de pozo con el enfoque descrito en base a mi prefacio y requisitos?

  2. ¿Se está realizando una solicitud de salida a Facebook para verificar el token de acceso (pasos 6 a 8 anteriores) por solicitud del cliente requerida / recomendada?

    Sé al menos que debo verificar el token de acceso que proviene de la solicitud del cliente. Sin embargo, el enfoque recomendado para verificaciones posteriores después del primero me es desconocido. Si hay patrones típicos, me interesa escuchar sobre ellos. Entiendo que pueden depender de la aplicación en función de mis requisitos; sin embargo, simplemente no sé qué buscar todavía. Pondré la debida diligencia una vez que tenga una idea básica.

    Por ejemplo, posibles pensamientos:

    • Hash el token de acceso + par UserId después de que se complete la primera verificación y almacenarlo en un caché distribuido (accesible por todos los servidores web) con vencimiento igual a los tokens de acceso. En las solicitudes posteriores de los clientes, controle el par de token de acceso + userId y verifique su existencia en la memoria caché. Si está presente, entonces la solicitud está autorizada. De lo contrario, acceda a la API de gráficos de Facebook para confirmar el token de acceso. Supongo que esta estrategia podría ser factible si estoy usando HTTPS (que seré). Sin embargo, ¿cómo se compara el rendimiento?

    • La respuesta aceptada en esta pregunta de StackOverflow recomienda crear un token de acceso personalizado después de que se complete la primera verificación del token de usuario de Facebook. El token personalizado se enviará al cliente para solicitudes posteriores. Me pregunto si esto es más complejo que la solución anterior, sin embargo. Esto requeriría la implementación de mi propio Proveedor de Identidad (algo que quiero evitar porque, en primer lugar, quiero usar proveedores externos de identidades ...). ¿Hay algún mérito en esta sugerencia?

  3. ¿Está el campo signedRequest presente en la respuesta en el paso 3 anterior (mencionado here ), equivalente al parámetro de solicitud firmado here en el flujo de ''inicio de sesión de Canvas de juegos''?

    Parecen ser insinuados como equivalentes ya que los primeros enlaces a este último en la documentación. Sin embargo, me sorprende que la estrategia de verificación mencionada en la página de juegos no se mencione en la página "creación manual de un flujo de inicio de sesión" de la documentación web.

  4. Si la respuesta al # 3 es ''Sí'', ¿puede la misma estrategia de confirmación de identidad decodificar la firma y compararla con lo que se espera que se use en el lado del servidor?

    Me pregunto si esto se puede aprovechar en lugar de realizar una llamada saliente a la API de gráfico debug_token (paso n. ° 6 anterior) para confirmar el token de acceso como se recomienda here :

    Por supuesto, para hacer la comparación en el lado del servidor, la porción de solicitud firmada debería enviarse junto con la solicitud al servidor (paso n. ° 5 anterior). Además de la viabilidad sin sacrificar la seguridad, me pregunto cómo se compararía el rendimiento con la realización de la llamada saliente.

  5. Mientras estoy en ello, ¿en qué escenario / con qué propósito, persistiría el token de acceso de un usuario a una base de datos, por ejemplo? No veo un escenario en el que necesite hacer esto, sin embargo, puedo estar pasando por alto algo. Tengo curiosidad de que algunos escenarios comunes podrían ser para despertar algunos pensamientos.

¡Gracias!


Según lo que describes, sugeriría usar un flujo de inicio de sesión del lado del servidor como se describe en

para que el token ya esté en su servidor y no necesite ser pasado del cliente. Si usa conexiones no cifradas, esto podría suponer un riesgo de seguridad (por ejemplo, para ataques de hombre en el medio).

Los pasos serían:

(1) Registrando personas en

Debe especificar el permiso que desea recopilar de los usuarios en el parámetro scope . La solicitud se puede activar solo a través de un enlace normal:

GET https://www.facebook.com/dialog/oauth? client_id={app-id} &redirect_uri={redirect-uri} &response_type=code &scope={permission_list}

Ver

(2) Confirmar la identidad

GET https://graph.facebook.com/oauth/access_token? client_id={app-id} &redirect_uri={redirect-uri} &client_secret={app-secret} &code={code-parameter}

(3) Inspeccione el token de acceso

Puedes inspeccionar el token como ya dijiste en tu pregunta a través de

GET /debug_token?input_token={token-to-inspect} &access_token={app-token-or-admin-token}

Esto solo debe hacerse desde el servidor, porque de lo contrario haría que el token de acceso a la aplicación sea visible para los usuarios finales (¡no es una buena idea!).

Ver

(4) Extender el token de acceso

Una vez que obtuviste el token (de corta duración), puedes hacer una llamada para extender el token como se describe en

como el siguiente:

GET /oauth/access_token?grant_type=fb_exchange_token &client_id={app-id} &client_secret={app-secret} &fb_exchange_token={short-lived-token}

(5) Almacenamiento de tokens de acceso

Con respecto al almacenamiento de los tokens en el servidor, FB sugiere hacerlo:

(6) Manejo de tokens de acceso caducados

Como FB no le notifica si un token ha caducado (y si no guarda la fecha de caducidad y lo compara con la marca de tiempo actual antes de realizar una llamada), es posible que reciba mensajes de error de FB si el token no es válido (después de un máximo de 60 días). El código de error será 190 :

{ "error": { "message": "Error validating access token: Session has expired at unix time SOME_TIME. The current unix time is SOME_TIME.", "type": "OAuthException", "code": 190 } }

Ver

Si el token de acceso deja de ser válido, la solución es hacer que la persona vuelva a iniciar sesión, momento en el que podrá realizar llamadas a la API en su nombre una vez más. El flujo de inicio de sesión que utiliza su aplicación para las personas nuevas debe determinar qué método debe adoptar.