Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [inne][PHP]Google OAuth2 problematyczny refresh token
Forum PHP.pl > Forum > Przedszkole
phpamator
Hej, ho, and witalis!
Panie i Panowie, They, Them and ktokolwiek jeszcze tam co by nikogo nie urazic ...
buduje w mojej laravelowej aplikacji wysylke przed google workspace z uzyciem OAuth2 do autentykacji ale
napotkalem problem z ktorym do tej pory sobie nie poradzilem.
Utworzylem aplikacje w Google, ustawilem scopes i wszystko dziala ale nie zwraca mi refresh tokena przy pierwszej autoryzacji. Przekopalem caly internet i wszystko co znalazlem to dodaj :
$client->addScope("email");
$client->acccess_type("offline");
$client->addScope("profile");
$client->setApprovalPrompt('force');

co uczynilem nie zmieniilo to jednak niczego, wyrzucilem polaczenie z konta Google, wywlilem rekordy z bazy zeby na czysto zainicjowac ponownie autoryzacje, pobranie tokenow itd
i nic, tak samo jak wczesniej dostaje token autoryzacyjny, emaila a refresh tokena jak nie bylo tak niema

Macie jakies doswiadczenie w tej kwestii ?
Podpowiedzcie jak zmusic Google zeby zwrocil refresh token

U innych providerow nie mialem problemu, nawet Zoho,Yahoo, Outlook365 , microsoft dzialaja bez najmniejszych problemow a G..... nie chce wspolpracowac

  1. private function processGoogleClientConnection($sender)
  2. {
  3. Log::channel('mailcheck')->info("Processing Google Client connection for sender: {$sender->sender_id}");
  4.  
  5. // Initialize the Google Client
  6. $client = new Google_Client();
  7. $client->setClientId(env('GOOGLE_CLIENT_ID'));
  8. $client->setClientSecret(env('GOOGLE_CLIENT_SECRET'));
  9. $client->setRedirectUri(env('GOOGLE_REDIRECT_URI'));
  10. $client->setAccessType('offline'); // Make sure to set this to get the refresh token
  11. $client->addScope(Google_Service_Gmail::GMAIL_SEND);
  12. $client->addScope(Google_Service_Gmail::GMAIL_READONLY);
  13. $client->addScope("email");
  14. $client->accessType('offline');
  15. $client->addScope("profile");
  16. $client->setApprovalPrompt('force'); // Forces the consent screen to get the refresh token
  17.  
  18. // Assuming $sender->code contains the OAuth2 code after user authorization
  19. $code = $sender->code; // The authorization code from Google
  20.  
  21. // Send the POST request to get the OAuth token
  22. $response = Http::asForm()->post('https://oauth2.googleapis.com/token', [
  23. 'code' => $code,
  24. 'client_id' => env('GOOGLE_CLIENT_ID'),
  25. 'client_secret' => env('GOOGLE_CLIENT_SECRET'),
  26. 'redirect_uri' => env('GOOGLE_REDIRECT_URI'),
  27. 'grant_type' => 'authorization_code',
  28. 'access_type' => 'offline', // This ensures you get a refresh token
  29. 'prompt' => 'consent' // Forces the consent screen, needed for refresh token
  30. ]);
  31.  
  32. // Check if the request was successful
  33. if ($response->failed()) {
  34. Log::channel('mailcheck')->error("Google OAuth token request failed for sender: {$sender->sender_id}");
  35. return []; // Or handle the error appropriately
  36. }
  37.  
  38. // Get the response data
  39. $data = $response->json();
  40.  
  41. // Log the tokens to ensure we're receiving them
  42. Log::channel('mailcheck')->info('Access Token: ', ['access_token' => $data['access_token']]);
  43. Log::channel('mailcheck')->info('Refresh Token: ', ['refresh_token' => $data['refresh_token'] questionmark.gif 'No refresh token']);
  44.  
  45. // Save the tokens to the database
  46. $emailProvider = $sender->emailProvider;
  47. $emailProvider->provider_name = 'google';
  48. $emailProvider->api_id = '2';
  49. $emailProvider->access_token = $data['access_token'];
  50. $emailProvider->refresh_token = $data['refresh_token'];// questionmark.gif null;
  51. $emailProvider->save();
  52.  
  53. // Check if access token and refresh token are present
  54. $accessToken = $sender->access_token;
  55. $refreshToken = $sender->refresh_token;
  56.  
  57. if (!$accessToken || !$refreshToken) {
  58. Log::channel('mailcheck')->error("Missing access or refresh token for sender: {$sender->sender_id}");
  59. return [];
  60. }
  61.  
  62. // Set the access token
  63. $client->setAccessToken($accessToken);
  64.  
  65. // Refresh the access token if expired
  66. if ($client->isAccessTokenExpired()) {
  67. Log::channel('mailcheck')->info("Google Client token expired, refreshing...");
  68.  
  69. $client->fetchAccessTokenWithRefreshToken($refreshToken);
  70. $newAccessToken = $client->getAccessToken();
  71. $sender->access_token = $newAccessToken['access_token'];
  72. $sender->save();
  73. }
  74.  
  75. // Create the Gmail service instance
  76. $service = new Google_Service_Gmail($client);
  77.  
  78. try {
  79. Log::channel('mailcheck')->info("Successfully connected to Google Gmail API for sender: {$sender->sender_id}");
  80.  
  81. // Fetch all messages in the inbox (no date range)
  82. $messagesResponse = $service->users_messages->listUsersMessages('me', [
  83. 'maxResults' => 100 // You can adjust the number here to limit the results
  84. ]);
  85.  
  86. // Log the raw API response to verify if emails are returned
  87. Log::channel('mailcheck')->info("Google API raw response: " . json_encode($messagesResponse));
  88.  
  89. $emails = [];
  90. foreach ($messagesResponse->getMessages() as $message) {
  91. $messageDetails = $service->users_messages->get('me', $message->getId());
  92.  
  93. // Log the email details to see the headers and body
  94. Log::channel('mailcheck')->info("Message Details: " . json_encode($messageDetails->getPayload()->getHeaders()));
  95.  
  96. $body = $this->getEmailBody($service, $messageDetails);
  97. Log::channel('mailcheck')->info("Email Body: " . $body);
  98.  
  99. $emails[] = [
  100. 'headers' => $messageDetails->getPayload()->getHeaders(),
  101. 'body' => $body,
  102. ];
  103. }
  104.  
  105. // Log the number of emails found
  106. $emailsCount = count($emails);
  107. Log::channel('mailcheck')->info("Found $emailsCount emails in INBOX for sender {$sender->sender_id}.");
  108.  
  109. return $emails;
  110.  
  111. } catch (\Google_Service_Exception $e) {
  112. Log::error("Google API error for sender {$sender->sender_id}: " . $e->getMessage());
  113. return [];
  114. } catch (\Exception $e) {
  115. Log::error("Error fetching emails for sender {$sender->sender_id}: " . $e->getMessage());
  116. return [];
  117. }
  118. }


Podpowiedzcie prosze

Pozdrawiam
phpamator


Może zamiast używać GoogleCLienta lepiej użyć Socialite ?
(moja aplikacja jest na Laravelu)
Danuta777

Wygląda na to, że problem z brakiem refresh tokena może wynikać z niewłaściwej konfiguracji aplikacji Google. Spróbuj zamiast ręcznego tworzenia klienta, użyć Laravel Socialite, który powinien załatwić sprawę lepiej.
Upewnij się też, że scope?y w aplikacji Google są ustawione poprawnie ? np. openid, email, profile, https://www.googleapis.com/auth/gmail.send, https://www.googleapis.com/auth/gmail.readonly.

Sprawdź też logi, co dokładnie zwraca Google podczas autoryzacji. Często refresh token nie jest zwracany, gdy aplikacja nie ma odpowiednich uprawnień.

Może to pomoże! smile.gif
phpamator
Hej, tak zrobiłem i pięknie działa, teraz mam problem z Zoho,
Ale nie widzę, żeby Zoho był obsługiwany przez Socialite, też nie zwraca tokenów
szukam dalej

Google już śmiga, problem był zupełnie gdzies indziej
(znaczy Google CLient był także ale zamieszałem z clallback uri's miałem w 2 miejscach odwołanie do tego samego ale w zupełnie innym flow)

Dzięki


Brak czytelne i jasnej dokumentacji to chyba największa bolączka.
Właśnie rozpykałem Zoho ale muszę powiedzieć, że takiech niejasności chyba w żadnym z dotychczasowych API nie widziałem ....
co Chindusy to Chindusy ...
...
ważne że w końcu działa
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.