skip to Main Content

In a Laravel App I try to get permission to save files on a Google Drive. As part of calling the api one can pass query parameters that should be returned.

Like this:

$client = new Client([
            'client_id' => config('services.google-drive.client_id'),
            'client_secret' => config('services.google-drive.client_secret'),
            'scopes' => [
                'https://www.googleapis.com/auth/drive.file',
                'https://www.googleapis.com/auth/drive',
            ],
            'redirect_uri' => route('users.integrations.google-drive.connect'), // NOTE: I do add the parameters here
            'approval_prompt' => 'force',
            'access_type' => 'offline',
        ]);


$authUrl = $client->createAuthUrl($client->getScopes(), ['igd' => $idg]);

$authUrl is:

https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=offline&client_id=XXXXXXXX&redirect_uri=YYYYYY&state&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&approval_prompt=force&igd=99df36fb-ee4a-4861-8d57-85b0b2905bcd

The last parameter is from my app so I send it to Google.

After approving the request the ‘callback’ url looks like this:

https://<my_return_url>?code=4%2F0Adeu5BWppRGhaAsAwDlDxbAMhbFIaEqk1rSHNdMKuQcKe-JXwcTE8fZZmMY3xLSv8XSs7g&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file

The ‘igd’ parameter is missing.

Any hint why ?

Thanks.
Kind regards
Steen

2

Answers


  1. Chosen as BEST ANSWER

    Thanks for your answer, but it's not 100% correct.

    Even with the above, one might not get the query parm back - for whatever reason

    What I have found to be working is a call to $client->setState('my_value')

    then in my callback I check for the 'state' key in the request

    I have also found out why you sometins don't get the refresh token, it is due to fact that you have already have some kind of connection.

    If you do not get the refresh token, then you can go to the google account and look at connections and then manually disconnect or try to call the $client->revokeToken()

    Here is a few methods that works for me - my specific use case

    NOTE: UserIntegrationGoogleDrive $integrationGoogleDrive is just a record in the db to store some information

    public function getGoogle_Client()
    {
        $client = new Client();
        //NOTE: This is not the credentials to the users Google Drive, but our app
        // So basically, our app asks for permission to save on the users Google Drive
        try {
            $client->setClientId(config('services.google-drive.client_id'));
            $client->setClientSecret(config('services.google-drive.client_secret'));
            $client->setRedirectUri(route('users.integrations.google-drive.callback'));
    
            $client->addScope('https://www.googleapis.com/auth/drive.file');
            $client->setAccessType('offline');
            $client->setApprovalPrompt('force');
        
        } catch (Exception $exception) {
            Log::error($exception->getMessage());
        }
        
        return $client;
    }
      
    public function connect(UserIntegrationGoogleDrive $integrationGoogleDrive)
    {
        $client = $this->getGoogle_Client();
        $client->getCache()->clear();
        $client->setState($integrationGoogleDrive->id);
    
        return redirect()->to($client->createAuthUrl());
    }
        
    public function callback(Request $request, string $data = null)
    {
        $client = $this->getGoogle_Client();
    
        if ($request->get('code')) {
            $token = $client->fetchAccessTokenWithAuthCode($request->get('code'));
            $integrationGoogleDrive = UserIntegrationGoogleDrive::find($request->get('state'));
    
            // We will save the access token, also without the refresh_token, just in case the user wan ut to 'revoke'
            if ($integrationGoogleDrive) {
                $integrationGoogleDrive->access_token = json_encode($token);
                $integrationGoogleDrive->save();
            }
    
            if (! isset($token['refresh_token'])) {
                Log::error('No refresh token');
                Log::error($request->all());
    
                return redirect()->route('users.integrations.google-drive.manual-disconnect', $integrationGoogleDrive->id);
            }
    
            return redirect()
                ->route('users.integrations.google-drive.connect-ok');
        }
    
        Log::error('Unsupported callback');
        Log::error($request->all());
    
        return redirect()->route('users.integrations.google-drive.connect-error');
    }
    

  2. you are missing a step you need to exchange the code for the access token

    // Exchange authorization code for an access token.
    $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
    $client->setAccessToken($accessToken);
    
           
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search