El flujo de autorización OAuth2 permite que nuestras aplicaciones accedan a parte de la información del usuario sin que este tenga que cedernos su identidad.
En ambos casos necesitaremos registrar una aplicación en el servicio externo, configurar cierta información como las URLs a las que debe volver cuando el cliente se loguea correctamente y guardar la Api key, el id de la aplicación e información específica que nos va a solicitar el servicio externo para realizar las solicitudes.
En estos enlaces está la información de Google y Microsoft sobre como crear la aplicación es sus servicios
El proceso que vamos a seguir en ambos casos es relativamente sencillo, si no tenemos el token de acceso almacenado en sesión le pediremos al servicio externo un enlace para que el cliente se pueda loguear lo que nos va a devolver a una pagina de nuestra aplicación con un codigo, utilizaremos el codigo para solicitar un token de acceso para nuestra aplicación en nombre del usuario el cual guardaremos en sesión. Ese token de acceso es que usaremos en peticiones al servicio externo.
Ahora veamos como realizar el proceso en una aplicación Symfony para Google y Microsoft.
Instalamos el paquete de Google para usar su API
composer require google/apiclient
Lo configuramos según la documentación
Creamos un cliente
$client = new \Google\Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->setRedirectUri('https://localhost/google/');
$client->addScope(\Google\Service\Calendar::CALENDAR);
$client->addScope(\Google\Service\Calendar::CALENDAR_EVENTS);
Los valores de $clientId y $clientSecret son los de la aplicación que hemos registrado en sus servicios, la Url de redirección puede ser localhost para tests, los scopes van a determinar a que información vamos a acceder em este ejemplo calendarios y eventos.
Comprobamos si nos han devuelto el codigo como parámetro GET, si es así obtenemos el token de acceso y lo almacenamos en sesión.
$code = $request->query->get('code', null);
if ($code != null) {
$token = $client->fetchAccessTokenWithAuthCode($code, $session->get('codeVerifier'));
$session->set('token', $token);
}
Leemos de sesión el token si no existe generaremos Url de autorización y un verificador de la autorización.
if ($token != null) {
$client->setAccessToken($token);
} else {
$session->set('codeVerifier', $client->getOAuth2Service()->generateCodeVerifier());
$authUrl = $client->createAuthUrl();
}
Microsoft (Graph v1)
Instalamos los paquete necesarios para usar su API
composer require microsoft/microsoft-graph league/oauth2-client
Creamos un cliente
$client = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => 'https://localhost/microsoft/',
'urlAuthorize' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
'urlAccessToken' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
'urlResourceOwnerDetails' => '',
'scopes' => 'user.read mail.read mail.send calendars.read'
]);
Los valores de $clientId y $clientSecret son los de la aplicación que hemos registrado en sus servicios, la Url de redirección puede ser localhost para tests, los scopes van a determinar a que información vamos a acceder en este ejemplo calendarios y mail.
Comprobamos si nos han devuelto el codigo como parámetro GET, si es así obtenemos el token de acceso y lo almacenamos en sesión.
$state = $request->query->get('state', null);
if ($state != null) {
$authCode = $request->query->get('code', null);
if ($authCode == null) {throw new \Exception('Auth code not received');}
$accessToken = $client->getAccessToken('authorization_code', [
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
'code' => $authCode
]);
$session->set('accessToken', $accessToken);
}
Leemos de sesión el token si no existe generamos Url de autorización y un verificador de la autorización.
$accessToken = $session->get('accessToken', null);
if ($accessToken == null) {
$session->set('oauthState', $client->getState());
$authUrl = $client->getAuthorizationUrl();
}
Microsoft (Graph v2)
Instalamos los paquete necesarios para usar su API
composer require microsoft/microsoft-graph league/oauth2-client
$state = $request->query->get('state', null);
if ($state != null) {
$authCode = $request->query->get('code', null);
if ($authCode == null) {throw new \Exception('Auth code not received');}
$tokenRequestContext = new AuthorizationCodeContext(
'common',
$_ENV['CLIENT_ID'],
$_ENV['CLIENT_SECRET'],
$authCode,
'https://localhost/microsoft/'
);
}
Comprobamos si nos han devuelto el codigo como parámetro GET, si es así obtenemos el token de acceso y hacemos una petición para obtener el token de acceso.