Como solicitar acceso a la cuenta de un usuario con Oauth 2.0 y PHP
No voy a decir que en la documentación de Google no venga explicado, porque viene, pero a veces resulta complicado seguir el hilo debido a que viene todo desglosado por muchas partes.
Lo que yo voy a explicar te dará acceso para lo siguiente:
- Solicitar acceso a un Scope de un usuario. Un Scope no es mas que un acceso de Lectura/Escritura a un servicio de Google(Analytics, Google Search….), puedes ver todos los scopes de los servicios de Google aquí.
- Recoger un access_token y un refresh_token que te permita utilizar para siempre el servicio del usuario sin necesidad de volver a solicitar acceso. (Siempre y cuando el usuario no cancele el permiso desde su cuenta)
- Actualizar el access_token con el refresh_token una vez que se caduque y poder volver a usar el servicio.
Requerimiento, pasos previos, antes de ponernos con el código:
- Necesitamos un client_id y un secret, esto se configura en Cloud Console.
- Tener habilitados los servicios de API en Cloud Console que vamos a utilizar.
- Necesitamos tener instalada la librería de servicios de Google para PHP.
Pasos previos:
1- Obtener client_id y secret en Cloud Console.
Para ello vamos a la pagina de credenciales de Google Cloud Console y creamos una nueva autorización de Id De cliente de Oauth:
En la selección de tipo de cliente, elegiremos Web. Y pondremos la URL de redirección tal y como la pongo a continuación.
Como vemos, en la URIs de redireccion autorizados he puesto: http://TUDOMINIO.COM/oauth2callback.php
Donde dice TUDOMINIO.COM introducimos nuestro dominio. Hablaremos del fichero oauth2callback.php cuando vayamos a crearlo.
Una vez creado, nos proporcionará el ID de Cliente y el SECRET (Esta clave de a continuación es de prueba y no funciona, debéis crear las vuestras) :
Ahora creamos un fichero en el servidor «client_secrets.json» con la siguiente información, para este ejemplo debe estar en la raiz, modificad los campos client_id, client_secret y redirect_uris:
{ "web": { "client_id": "PEGAMOS AQUÍ EL ID DE CLIENTE", "client_secret": "PEGAMOS AQUÍ EL SECRET", "redirect_uris": ["http://MIDOMINIO.com/oauth2callback.php"], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token" } }
2. Tener habilitados los servicios de API en Cloud Console que vamos a utilizar.
Debemos habilitar las APIs que vayamos a usar en la biblioteca de Google Cloud Console. Buscamos por el Servicio que vayamos a usar y lo habilitamos.
3. Necesitamos tener instalada la librería de servicios de Google para PHP
Voy a obviar que tienes ya las librerías de Google Services dentro de la carpeta vendor y que lo has actualizado con composer. Si este paso no lo has hecho, hazlo, puedes seguir la siguiente documentación para instalar la librería de servicios de Google aquí.
Ahora vamos a la parte en la que solicitamos el acceso a un usuario para usar sus datos a través de la API.
Como solicitar acceso a un Scope de un usuario y cual es el codigo que debo utilizar.
Creamos un fichero «index.php» con el siguiente código, leed bien los pasos para comprender que queremos conseguir:
<?php // 1- Cargamos las librerias de los servicios de Google. require_once __DIR__.'/vendor/autoload.php'; // 2- Verificamos si para este usuario en concreto ya hemos solicitado acceso en algún momento. // 3- Si no hemos solicitado acceso en ningún momento, procedemos a solicitar acceso para recoger el access_token y el refresh_token para almacenarlos. // 4- Si ya hemos solicitado acceso en algún momento, recogemos el access_token y el refresh_token (almacenados en bbdd o en algún fichero en local) y los asignamos en una variable. //El objetivo es conseguir el access_token y el refresh_token del usuario. //Teniendo estos dos token podremos acceder siempre a sus datos sin solicitar acceso. //A no ser que nos revoque DESDE LA ADMINISTRACIÓN DE SU CUENTA el acceso a nuestra aplicación web.
El primer paso de cargar las librerías ya lo tenemos con la linea
require_once __DIR__.'/vendor/autoload.php';
Vamos al segundo paso. Verificar si para el usuario que está utilizando nuestra web ya le solicitamos acceso en algún momento, si ya solicitamos acceso tendremos almacenados su último access_token y su refresh_token.
Vamos a explicar para que sirven el access_token y para que es el refresh_token.
El access_token, como su palabra indica nos permite acceder a los datos de los servicios del usuario al que corresponde. Este access_token tiene un tiempo de vida, pasado ese tiempo de vida no sirve para nada.
El refresh_token, nos permite actualizar de manera «offline», sin necesidad de ninguna acción por parte del usuario, un nuevo access_token.
Teniendo claros esos conceptos, vamos al paso 2.
// 2- Verificamos si para este usuario en concreto ya hemos solicitado acceso en algún momento. // Miramos en nuestra BBDD o donde quiera que guardemos la información si tenemos el refresh_token y el access_token. //Si los tenemos simplemente pues los recogemos y los asignamos a las variables. //$access_token = EL ACCESS TOKEN RECOGIDO DE DONDE SEA. //$refresh_token = EL REFRESH TOKEN RECOGIDO DE DONDE SEA.
Vamos a suponer que no disponemos del access_token ni del refresh_token, vamos al paso 3 para solicitar al usuario acceso al servicio.
Para ello usamos el siguiente código:
// 3- Si no hemos solicitado acceso en ningún momento, procedemos a solicitar acceso para recoger el access_token y el refresh_token para almacenarlos. $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
Aquí necesitamos crear otro fichero llamado oauth2callback.php con el siguiente codigo:
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google_Client(); $client->setAuthConfigFile(__DIR__.'/client_secrets.json'); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); //Aqui tenemos que poner los SCOPES que vamos a solicitar. $client->addScope(array("SCOPE1", "SCOPE2", "SCOPE3")); //Tipo de acceso $client->setAccessType("offline"); $client->setIncludeGrantedScopes(true); $client->setApprovalPrompt('force'); if (! isset($_GET['code'])) { $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { $resultTokens = $client->authenticate($_GET['code']); //La variable $resultTokens tiene el refresh_token. Por lo que tendremos que almacenarlo. //Llamamos a la función que guardaEnBBDD($resultTokens['refresh_token'] ); //Ahora solicitamos el access_token. $_SESSION['access_token'] = $client->getAccessToken(); //Guardamos el access_token. //guardarAccessTokenEnBBDD( $_SESSION['access_token'] ); //Volvemos a nuestro script inicial. $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
Con el access_token ya podremos realizar las funciones que queramos.
Bastará con crear un «client» de Google Services. Con el siguiente codigo:
$client = new Google_Client(); $client->setAuthConfig(__DIR__.'/client_secrets.json'); //La variable $accessToken es la que hemos guardado antes en BBDD. $client->setAccessToken($accessToken); //La variable $refreshToken es la que hemos guardado antes en BBDD. $client->refreshToken($refreshToken); //Este es un ejemplo con analytics: $analytics = new Google_Service_AnalyticsReporting($client);
Con esto ya tenemos funcionando nuestra app y recogiendo los datos del cliente.
Como recurso adicional, puede que venga bien el acceso a Oauth Playground de Google:
https://developers.google.com/oauthplayground/