laravelyoutube-data-apigoogle-client

YouTube DATA API V3 does not return refresh token


I have almost looked through all the answers to this question and have not been able to solve my problem. I tried different options but can't get refresh token. Here's an example of my code.

$googleClient = new \Google_Client();
$redirectUrl = url('***');
$googleClient->setClientId(config('services.google_api_key.client_id'));
$googleClient->setClientSecret(config('services.google_api_key.client_secret'));
$googleClient->setScopes(config('services.google_api_key.scopes'));
$redirect = filter_var($redirectUrl);
$googleClient->setRedirectUri($redirect);
$googleClient->setAccessType('offline');
$googleClient->setApprovalPrompt('force');

if ($request->has('code')) {
    $googleClient->authenticate($request->get('code'));
    $token = $googleClient->getAccessToken();
    dd($token);
}

And it returned only these data

[
  "access_token" => "***"
  "expires_in" => 3599
  "scope" => "https://www.googleapis.com/auth/youtube"
  "token_type" => "Bearer"
  "created" => 1613189613
]

I know that the refresh token is provided only on the first call, and so I tried to use this method $googleClient->revokeToken($token); to get it again, but it didn't help, and I already spent a whole day trying to solve this problem and could not. Please help me solve this problem. I understand that I am making a mistake somewhere, but I cannot understand where. Thanks in advance.


Solution

  • I finally found the problem and would like to explain in detail what was the reason, maybe someone else will come in handy. And so I created everything as it was described in the official documentation https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps#obtainingaccesstokens. I used this code and was unable to get the refresh token.

    $googleClient = new \Google_Client();
    $redirectUrl = url('***');
    $googleClient->setClientId(config('services.google_api_key.client_id'));
    $googleClient->setClientSecret(config('services.google_api_key.client_secret'));
    $googleClient->setScopes(config('services.google_api_key.scopes'));
    $redirect = filter_var($redirectUrl);
    $googleClient->setRedirectUri($redirect);
    $googleClient->setAccessType('offline');
    $googleClient->setApprovalPrompt('force');
    
    if ($request->has('code')) {
        $googleClient->authenticate($request->get('code'));
        $token = $googleClient->getAccessToken();
        dd($token);
    }
    

    The official documentation says this:

    $client = new Google_Client();
    $client->setAuthConfig('client_secret.json');
    $client->addScope(GOOGLE_SERVICE_YOUTUBE::YOUTUBE_FORCE_SSL);
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
    // offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType('offline');
    // Using "consent" ensures that your application always receives a refresh token.
    // If you are not using offline access, you can omit this.
    $client->setApprovalPrompt("consent");
    $client->setIncludeGrantedScopes(true);   // incremental auth
    

    Pay attention to this part:

    // Using "consent" ensures that your application always receives a refresh token.
    // If you are not using offline access, you can omit this.
    $client->setApprovalPrompt("consent");
    

    And this is what I managed to find out

    $client->setApprovalPrompt('force'); // works
    $client->setApprovalPrompt('consent'); // doesn't work
    $client->setPrompt('consent'); // works
    

    For 'consent' setApprovalPrompt() doesn't work, but I could not find about it in the official documentation. And found this error from here https://github.com/googleapis/google-api-php-client/issues/1795. My final code looks like this which works fine and returns me a refresh token:

    $redirectUrl = url('my_callback_url');
    $client = new \Google_Client();
    $client->setClientId(config('services.google_api_key.client_id'));
    $client->setClientSecret(config('services.google_api_key.client_secret'));
    $client->addScope(config('services.google_api_key.scopes'));
    $client->setState(substr(md5(time()), 0, 15));
    $client->setRedirectUri($redirectUrl);
    $client->setAccessType('offline');
    $client->setPrompt('consent');
    $client->setIncludeGrantedScopes(true);
    return $client->createAuthUrl();
    

    Thank you stvar for your answer, after that I started to read the documentation all over again and look for the reason.