Conectando Laravel Socialite com a biblioteca PHP do cliente do Google

A autenticação OAuth se tornou um padrão para aplicativos da web, permitindo que os usuários façam login usando suas contas existentes de serviços como o Google. O Laravel Socialite torna esse processo simples, mas e se você quiser ir além da autenticação simples e acessar as APIs do Google, como o Calendar? Este artigo o guiará pela configuração do Laravel Socialite com o Google OAuth e a conexão com a Google Client PHP Library.
Configurando o Laravel Socialite
Primeiro, crie um novo projeto Laravel e instale o Socialite:
composer create-project laravel/laravel googlecomposer require laravel/socialite
Adicione credenciais do Google OAuth ao seu
config/services.php
arquivo:
'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => 'http://localhost:8000/auth/callback',],
Criando credenciais do Google OAuth
Como tem muitos passos, essa parte é sempre um pouco complicada.
- Acesse o Google Cloud Console
- Navegue até "APIs e serviços > Credenciais"
- Configure sua tela de consentimento do OAuth caso ainda não tenha feito isso
- Clique em "Criar credenciais" e selecione "ID do cliente OAuth"
- Escolha "Aplicativo Web" como seu tipo de aplicativo e dê um nome a ele
-
Adicione um URI de redirecionamento autorizado (por exemplo,
http://localhost:8000/auth/callback
ouhttp://yoursite.test/auth/callback
se estiver usando Laravel Herd) - Após a criação, você receberá seu Client ID e Client Secret. Você os adicionará ao seu arquivo .env como GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET. Você também precisará do arquivo de credenciais baixado como JSON. Clique em "Download JSON" para obter este arquivo.
-
Renomeie este novo arquivo JSON como oauth-credentials.json e coloque-o em
storage/app/private/google/oauth-credentials.json
Implementação básica do Socialite
Configure rotas no seu
routes/web.php
arquivo para redirecionamento e retorno de chamada do OAuth. Fiz alterações na configuração típica para armazenar tokens como arquivos e incluí uma rota que usaremos para manipular tokens de atualização:
Route::get('/auth/redirect', function (){ return Socialite::driver('google') ->scopes(['https://www.googleapis.com/auth/calendar']) ->with([ 'prompt' => 'consent', ]) ->redirect();}); Route::get('/auth/refresh', function (){ $refreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json'); $newTokens = Socialite::driver('google')->refreshToken($refreshToken); if($newTokens->token) { Storage::disk('local')->put('google/oauth-token.json', $newTokens->token); } if($newTokens->refreshToken) { Storage::disk('local')->put('google/oauth-refresh-token.json', $newTokens->refreshToken); } return redirect('/gmail');}); Route::get('/auth/callback', function (){ $googleUser = Socialite::driver('google')->user(); Storage::disk('local')->put('google/oauth-token.json', $googleUser->token); if($googleUser->refreshToken) { Storage::disk('local')->put('google/oauth-refresh-token.json', $googleUser->refreshToken); } $expiresIn = $googleUser->expiresIn; Auth::login($user); return redirect('/dashboard');});
Autorização
Visite
http://localhost:8000/auth/redirect
para fazer login. Agora você deve ver uma tela de login do Google.
Expandindo o escopo do OAuth para acesso ao Google Agenda
Digamos que você queira expandir a utilidade dessa troca de tokens OAuth. Ela tem sido ótima para fazer com que os usuários façam login no seu aplicativo da web, mas agora você quer que os usuários vejam eventos do Google Agenda deles. Podemos alterar o escopo do nosso acesso OAuth para que buscar eventos do Google Agenda funcione. Para fazer isso, precisaremos de uma biblioteca diferente.
Para acessar os dados do Google Agenda, precisamos habilitar a API do Google Agenda.
-
Habilite a API do Google Agenda no Google Cloud Console:
- Vá para "APIs e serviços > Biblioteca"
- Search for and enable the Google Calendar API
-
Modify your redirect route to include the Calendar scope:
Route::get('/auth/redirect', function () { return Socialite::driver('google') ->scopes(['https://www.googleapis.com/auth/calendar']) ->redirect();});
Note: You can see a list of different scopes to Google products at https://developers.google.com/identity/protocols/oauth2/scopes
When you visit /auth/redirect
, you'll now be prompted to grant access to your Google Calendar.
Note: If you encounter a 403 error, add yourself as a test user under "Google Auth Platform > Audience > Test Users" in the Google Cloud Console.
Connecting to the Google Client PHP Library
But now what? How do you get that calendar data? Simply having the OAuth token isn't enough to access Google Calendar data. For this, we need another library.
I'm going to use the Google APIs Client Library for PHP.
composer require google/apiclient
Create a new route to access the Google Calendar API. Obviously a route might not be the best place for this, but it'll work.
use Google\Client; Route::get('/calendar', function (){ $client = new Client(); // Pluck the same tokens used for Socialite $oathCredentialsPath = Storage::disk('local')->path('google/oauth-credentials.json'); $refreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json'); $oathToken = Storage::disk('local')->get('google/oauth-token.json'); $client->setAuthConfig($oathCredentialsPath); $client->setAccessToken($oathToken); $client->addScope(\Google\Service\Calendar::CALENDAR_READONLY); $service = new \Google_Service_Calendar($client); $calendar_id = 'youremail@gmail.com'; $opt_params = array( 'maxResults' => 10, 'orderBy' => 'startTime', 'singleEvents' => true, 'timeMin' => date('c'), ); $results = $service->events->listEvents($calendar_id, $opt_params); dd($results); });
Now, using the tokens you already had from Socialite, you should see Google Calendar events back from the API.
Obtaining and Managing Refresh Tokens
For long-term API access, you'll need a refresh token. Eventually your access token will expire. We created a /auth/refresh
route for refreshing a token, but visiting that URL might not work for you the first time. If you don't have a storage/app/private/google/oauth-refresh-token.json
file, it will fail. Your first OAauth request likely didn't return a refresh token.
Force Google to provide one by adding the consent
prompt to your /auth/redirect route
:
Route::get('/auth/redirect', function () { return Socialite::driver('google') ->scopes(['https://www.googleapis.com/auth/calendar']) ->with([ 'prompt' => 'consent', ]) ->redirect();});
An Alternate Way to Handle Token Expiration and Refreshing
You don't have to redirect a user to /auth/refresh
for a refresh token, if you don't want. Here's an example of how to handle token refreshing when connecting to Google's APIs in an exception.
The key to making this work is the refreshToken()
method from Socialite.
try { // Your attempt to connect to Google API } catch (\Exception $e) { // Refresh Google auth token $oldRefreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json'); $newTokens = Socialite::driver('google')->refreshToken($oldRefreshToken); if ($newTokens->token) { Storage::disk('local')->put('google/oauth-token.json', $newTokens->token); } if ($newTokens->refreshToken) { Storage::disk('local')->put('google/oauth-refresh-token.json', $newTokens->refreshToken); } // Try to connect again after refreshing the token}
Conclusion
By combining Laravel Socialite with the Google Client PHP Library, you can create powerful applications that not only authenticate users but also interact with Google services like Calendar. This approach gives you the flexibility to expand your application's capabilities while maintaining a smooth authentication flow for your users. And it might be a little more efficient for you.
Remember to always handle tokens securely and implement proper error handling for API requests to ensure a secure and robust user experience.