Search code examples
oauth-2.0google-oauthredirect-uri

How to get past Google's OAUTH2 verification for desktop apps


I have set up a new Project and Client ID for use by a new 'desktop' application, which now needs authorization. Actually, the 'desktop' application is a batch process on a headless Linux server in this case.

The OAuth 2.0 for Mobile & Desktop Apps guide is Google's official instruction for obtaining the necessary Access Token and Refresh Token that such an application needs. In step 2: send a request ... is the following text:

The value must exactly match one of the authorized redirect URIs for 
the OAuth 2.0 client, which you configured in your client's API Console 
Credentials page. If this value doesn't match an authorized URI, you will
get a redirect_uri_mismatch error.

However, when creating a Desktop client, there appears to be no place to specify a Redirect URI in the API Credentials page. I've created a Web Client credentials on the same Google Developer's Console page, and that allows for a Redirect URL, but I don't see that at all on the Desktop client.

How can I obtain the tokens necessary to continue? Is there some other setting that I must choose in order or the Redirect URI option to show up on Desktop Credentials, or am I misreading this, or ????

EDIT as requested

(... after creating a client and setting appropriate parameters...) when I execute this code...

$client->setRedirectUri('http://web.lovelady.com/google-api-php-client/examples/large-file-download.php')'
$authUrl = $client->createAuthUrl();
printf("Open this link in your browser:\n%s\n", $authUrl);
printf('Enter verification code: ');
$authCode = trim(fgets(STDIN));

The resultant link ends with the redirect_uri_mismatch error as stated.

If I omit that first line (setRedirectUri()), then the link works and authorization takes place, but after authorization and my approval, there is a "page cannot be displayed" error


Solution

  • Here is my sample for Google drive with php and a desktop app. Let me know if it helps

    <?php
    require __DIR__ . '/vendor/autoload.php';
    
    if (php_sapi_name() != 'cli') {
        throw new Exception('This application must be run on the command line.');
    }
    
    use Google\Client;
    use Google\Service\Drive;
    
    /**
     * Returns an authorized API client.
     * @return Client the authorized client object
     */
    function getClient()
    {
        $client = new Client();
        $client->setApplicationName('Google Drive API PHP Quickstart');
        $client->setScopes('https://www.googleapis.com/auth/drive.readonly');
        $client->setAuthConfig('C:\Development\FreeLance\GoogleSamples\Credentials\credentials.json');
        $client->setAccessType('offline');
        $client->setRedirectUri("http://127.0.0.1");
        $client->setPrompt('select_account consent');
    
        // Load previously authorized token from a file, if it exists.
        // The file token.json stores the user's access and refresh tokens, and is
        // created automatically when the authorization flow completes for the first
        // time.
        $tokenPath = 'token.json';
        if (file_exists($tokenPath)) {
    
                $accessToken = json_decode(file_get_contents($tokenPath), true);
                $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                $client->setAccessToken($accessToken);
        }
    
        // If there is no previous token, or it's expired.
        if ($client->isAccessTokenExpired()) {
            // Refresh the token if possible, else fetch a new one.
            if ($client->getRefreshToken()) {
                $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
            } else {
                // Request authorization from the user.
                $authUrl = $client->createAuthUrl();
                printf("Open the following link in your browser:\n%s\n", $authUrl);
                print 'Enter verification code: ';
                $authCode = trim(fgets(STDIN));
    
                // Exchange authorization code for an access token.
                $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
    
                $client->setAccessToken($accessToken);
    
                // Check to see if there was an error.
                if (array_key_exists('error', $accessToken)) {
                    throw new Exception(join(', ', $accessToken));
                }
            }
            // Save the token to a file.
            if (!file_exists(dirname($tokenPath))) {
                mkdir(dirname($tokenPath), 0700, true);
            }
            file_put_contents($tokenPath, json_encode($client->getAccessToken()));
        }
        return $client;
    }
    
    
    // Get the API client and construct the service object.
    try {
        $client = getClient();
    }
    catch(Exception $e) {
    
        unlink("token.json");
        $client = getClient();
        }
    
    $service = new Drive($client);
    
    // Print the next 10 events on the user's calendar.
    try{
    
    
        $optParams = array(
            'pageSize' => 10,
            'fields' => 'files(id,name,mimeType)',
            'q' => 'mimeType = "application/vnd.google-apps.folder" and "root" in parents',
            'orderBy' => 'name'
        );
        $results = $service->files->listFiles($optParams);
        $files = $results->getFiles();
    
        if (empty($files)) {
            print "No files found.\n";
        } else {
            print "Files:\n";
            foreach ($files as $file) {
                $id = $file->id;
    
                printf("%s - (%s) - (%s)\n", $file->getId(), $file->getName(), $file->getMimeType());
            }
        }
    }
    catch(Exception $e) {
        // TODO(developer) - handle error appropriately
        echo 'Message: ' .$e->getMessage();
    }
    

    404 error

    After checking your video. I am happy to say that this is working as intended. The 404 is a result of the fact that you do not have a web server running on your machine. but if you check the url bar you will find the code you are looking for

    enter image description here

    copy the code and place it in the app the console window and it should run.