Explicación del protocolo OAuth 2
Tiempo de lectura: 4.68 minutos
Veamos qué es el protocolo OAuth y cómo funciona, a través de un ejemplo.
Introducción
OAuth 2 es un framework de autorización, que permite a las aplicaciones obtener acceso (limitado) a las cuentas de usuario de determinados servicios, como Facebook, GitHub, Twitter, Steam, BitBucket, LinkedIn y muchos más.
Consiste en delegar la autenticación de usuario al servicio que gestiona las cuentas, de modo que sea éste quien otorgue el acceso para las aplicaciones de terceros.
OAuth 2 provee un flujo de autorización para aplicaciones web, aplicaciones móviles e incluso programas de escritorio.
Roles presentes en OAuth
En el protocolo que define OAuth podemos identificar 4 roles.
- Client
- Resource Owner
- Resource Server
- Authorization Server
Veamos cuál es el rol que desempeña cada uno.
Client.- Es la aplicación cliente que quiere acceder a la cuenta de un usuario, en un servicio determinado. A fin de conseguir ello, debe contar con una autorización del usuario, y esta autorización se debe validar (a través de la API del servicio).
Resource Owner.- El "dueño del recurso" es el usuario que autoriza a una aplicación, para que pueda acceder a su cuenta. El acceso está limitado en función del "scope" que concede el usuario durante la autorización.
Resource & Authorization Server.- Resource server es el servidor que almacena las cuentas de usuarios, y authorization server es el servidor que verifica la identidad de los usuarios y emite access tokens
a la aplicación cliente.
Desde nuestro punto de vista como desarrolladores, la API del servicio representa muy bien a estos 2 últimos roles. Por tanto, podemos referirnos a ellos en conjunto, bajo el nombre de servicio o API.
Flujo del protocolo OAuth
El flujo descrito a continuación es un flujo genérico que representa al protocolo OAuth.
Sin embargo, podemos encontrar diferencias en función al authorization grant type
. Es decir, OAuth puede implementarse bajo diversas condiciones, y varía principalmente si se trata de una aplicación web, móvil o de escritorio.
-
La aplicación cliente solicita una autorización para acceder a los recursos de un usuario, en un servicio determinado.
-
Si el usuario autoriza esta solicitud, la aplicación recibe una
authorization grant
(concesión de autorización). -
La aplicación cliente solicita un
access token
alauthorization server
, demostrando que es un cliente válido, y el permiso concedido anteriormente. -
Si la identidad de la aplicación cliente se valida adecuadamente por el servicio, y la concesión de autorización es válida, el
authorization server
emite unaccess token
a la aplicación cliente. Con esto la autorización se ha completado. -
La aplicación cliente puede presentar el
access token
recibido en el paso anterior, y "solicitar un recurso" alresource server
. - Si el
access token
es válido, elresource server
hace entrega del recurso a la aplicación.
Es importante tener en cuenta que con "recurso" nos referimos generalmente a acceder a información del usuario, pero si la API del servicio lo permite (y el usuario nos lo ha autorizado), también es posible ejecutar acciones a nombre del usuario.
Nota:
- Puedes volver a leer los pasos anteriores y considerar al
authorization server
yresource server
como la API ofrecida del servicio, - ya que generalmente cuando un servicio (como Facebook o Twitter) implementa un servidor de OAuth2, la API que ponen a nuestra disposición desempeña ambos roles.
Explicación del protocolo OAuth (a través de un ejemplo)
Veamos cómo funciona OAuth, descrito muy de cerca a través de un ejemplo.
Imaginemos que queremos iniciar sesión vía Facebook.
En ese caso, se desarrolla la siguiente secuencia.
-
Un usuario entra a nuestra página (digamos que nuestra página se llama PYM), y hace clic en "Ingresar usando Facebook".
-
Nuestra aplicación lo va a redirigir a una URL como la siguiente:
facebook.com/oauth2/auth?client_id=ABC&redirect_uri=programacionymas.com/oauth_response
Ésta URL contiene los siguientes parámetros: un
client_id
, unaredirect_uri
y opcionalmente un parámetroscopes
(para indicar a qué información queremos acceder). -
Facebook primero va a ver si nuestro
client_id
es válido (comparándolo con la lista deoauth_client
permitidos). -
Si todo está correcto, entonces define una variable de sesión que guarda nuestro
client_id
yredirect_uri
. Y entonces:- Redirige al usuario a
facebook.com/login
(muestra un formulario de inicio de sesión) si el usuario aún no ha iniciado sesión. - O avanza directamente al siguiente paso si ya hay una sesión activa en Facebook.
- Redirige al usuario a
- Facebook muestra el logo de PYM y el nombre de la app (lo reconoce a partir del
client_id
), indicando al usuario: "Esta app quiere acceder a tus datos de Facebook, ¿le das permiso?" (según elscope
indicado previamente).
Si aceptamos, entonces ...
-
Facebook genera un código (que tiene un sólo uso válido para PYM, el usuario en cuestión y el scope solicitado). Facebook redirige al usuario según la
redirect_uri
indicada al inicio.Es decir, esta
redirect_uri
es una ruta usada como callback en nuestra aplicación para recibir el permiso otorgado por Facebook y hacer posible el inicio de sesión. -
Entonces Facebook enviará el código generado hacia la aplicación PYM:
programacionymas.com/oauth_response?code=aqui_un_codigo_extenso
. -
PYM toma el código que recibe de Facebook y vuelve a hacer una petición a Facebook, incluyendo ahora su
client_secret
.Esta última petición no se trata de una redirección a nivel de navegador, sino más bien de una solicitud de servidor a servidor.
Para probar su identidad, PYM hace una petición de la siguiente forma:
facebook.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=aqui_un_codigo_extenso
-
Facebook verifica que el código sea válido, y así mismo lo invalida en ese instante (recordar que son de uso único).
-
Entonces Facebook responde con un AccessToken, que PYM podrá usar (hasta que expire) para hacer peticiones a la API, en nombre del usuario que ha otorgado los permisos.
Por ejemplo, con este token podemos acceder a la información básica del usuario, y usar estos datos para crear una cuenta en nuestra aplicación. Pero un token, dependiendo de la API, nos permite también realizar acciones en nombre del usuario, en función a los permisos otorgados (el parámetro
scope
usado inicialmente determina los permisos que estamos solicitando al usuario).
Preguntas frecuentes
¿Por qué Facebook le pasa un código de uso único a PYM (la aplicación cliente) y no el AccessToken directamente?
Respuesta:
Porque Facebook necesita validar que realmente PYM ha solicitado el acceso.
El client_id
suele ser un dato que está expuesto (es público, ya que forma parte de la URL de Facebook a donde el usuario es redirigido desde un inicio).
Cualquiera podría hacer una petición usando dicho client_id
.
Pero existe un client_secret
que sólo PYM posee, y es justamente lo que se valida en este punto.
Si un "hacker" robó este dato (el client_secret
de una aplicación), podría tener los mismos permisos que fueron otorgados a esta aplicación cliente por parte de sus usuarios.
Entonces Facebook debe asegurar que quien solicitó los "recursos" sea el mismo que va a acceder a ellos. Y aquí es donde PYM se identifica ante Facebook con su client_secret
.
En vez de redirigir a una URL que contiene el "código extenso" como un parámetro, ¿por qué no Facebook lo envía a PYM directamente, de servidor a servidor?
Respuesta:
Cuando Facebook redirige al usuario a una ruta de PYM, lo hace principalmente para ceder el control del flujo a la aplicación cliente.
Es decir, todos queremos que la aplicación cliente continúe con el usuario, según lo que éste intentaba hacer inicialmente, ¿verdad?
Así, una vez que el usuario ha otorgado los permisos necesarios, la aplicación cliente y el usuario pueden continuar donde se quedaron ?