OAuth 2 es una estructura (framework) de autorización que les permite a las aplicaciones obtener acceso limitado a cuentas de usuario en un servicio HTTP, como Facebook, GitHub y DigitalOcean.
Delega la autenticación del usuario al servicio que aloja la cuenta del mismo y autoriza a las aplicaciones de terceros el acceso a dicha cuenta de usuario. OAuth 2 proporciona flujos de autorización para aplicaciones web y de escritorio; y dispositivos móviles.
Roles presentes en OAuth
En el protocolo que define OAuth podemos identificar 4 roles.
- Client
- Resource Owner
- Resource Server
- Authorization Server
- Veamos a qué hace referencia cada uno.
Client.- El cliente es la aplicación 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 ha concedido el usuario en 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, según las condiciones en que se está implementando OAuth; que 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 solicita un access token al authorization server (API) presentando su identidad, y el permiso concedido anteriormente.
- Si la identidad de la aplicación cliente se reconoce correctamente por el servicio, y la concesión de autorización es válida, el authorization server (API) emite un access token a la aplicación. Con esto la autorización se ha completado.
- La aplicación solicita un recurso al resource server (API) y presenta el correspondiente access token.
- Si el access token es válido, el resource server (API) hace entrega del recurso a la aplicación.
Con recurso generalmente nos referimos a acceder a una información del usuario, pero si la API del servicio lo permite (y el usuario nos lo ha autorizado), podríamos estar ejecutando acciones en nombre del usuario (a través del servicio).
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, una redirect_uri y opcionalmente un parámetro scopes (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 de oauth_client permitidos).
- Si todo está correcto, entonces define una variable de sesión que guarda nuestro client_id y redirect_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.
- 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 el scope 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. Facebook enviará un 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 un único uso).
- 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).