Google OAuth2/Calendar获取RefreshToken返回NULL问题求助
Hey there, let's break down why you're getting a NULL refresh token for your Google Calendar关联功能—this is a super common issue, and I've worked through it multiple times. Here are the most likely causes and fixes to check step by step:
1. Missing or Incorrect OAuth Scopes
Even if you set offline access, Google won't return a refresh token unless you request the right scopes for calendar access. Make sure you're explicitly adding the necessary scopes to your client configuration.
For example, add this line after initializing your Google_Client:
$client->addScope(Google_Service_Calendar::CALENDAR);
You can use more specific scopes like CALENDAR_READONLY if you don't need write access, but ensure the scope matches your app's requirements.
2. User Already Granted Access Without Offline Consent
If your users previously authorized your app before you added the offline access setting, Google will not automatically start returning refresh tokens for those existing authorizations. You need to force a re-consent prompt to generate a new token that includes the refresh token.
Add this line to your client setup:
$client->setPrompt('consent');
This will make the authorization page re-appear for users, even if they've granted access before, ensuring the new token includes a refresh token.
3. Mismatched Redirect URI or Invalid Client Secret
Double-check two critical settings in your Google Cloud Console:
- The redirect URI in your code must exactly match the one listed under your OAuth 2.0 Client ID (even trailing slashes matter).
- Ensure your
client_secret.jsonfile is the latest one downloaded from the Cloud Console—regenerating the secret or changing project settings can invalidate old files.
4. Outdated Google API Client Library
You're using version 2.2.1 of the Google PHP client, which was released in 2017. Older versions can have bugs related to token retrieval or deprecated methods that affect refresh tokens. Consider upgrading to the latest stable version of the library to rule out version-related issues.
5. Verify the Token Response Directly
When exchanging the authorization code for tokens, print the full response to see what Google is actually sending you. Sometimes the refresh token exists but your code isn't accessing it correctly.
Add this debug step after fetching the token:
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']); var_dump($token); // Check if 'refresh_token' is present in the array
If the refresh token is missing here, the issue is on Google's end based on your configuration; if it exists but your code isn't saving it, you'll need to fix your storage logic.
6. Testing Mode Limitations
If your OAuth consent screen is set to Testing mode in the Google Cloud Console, refresh tokens expire after 7 days. Once expired, you won't get a new refresh token unless the user re-consents. For production use, submit your app for verification and move it out of testing mode to get long-lived refresh tokens.
Start with adding the setPrompt('consent') and verifying your scopes—those are the most frequent fixes for this issue. If those don't work, work through the other checks one by one.
内容的提问来源于stack exchange,提问作者Kelly Larsen

