I'm trying to authenticate to use Google Sheets API. I'm starting to loose my mind over this, because I've been stuck at this problem for two days.
In my Google Console I have set the Credentials -> OAuth 2.0 Client IDs -> Authorized redirect URIs as https://stage.domain.com/
and https://stage.domain.com
.
When I visit https://stage.domain.com
, I'm redirected to the accounts.google.com to authorize my app. I select my account and click on "Allow" button. I'm redirected to the https://stage.domain.com/?code=4/...&scope=https://www.googleapis.com/auth/spreadsheets.readonly
and get the {"error":"redirect_uri_mismatch","error_description":"Bad Request"}
from $client->fetchAccessTokenWithAuthCode
function.
What am I doing wrong? I'm running PHP and I'm using google/apiclient^2.0
from Composer.
$configPath = __DIR__ . "/";
// This get's generated by the script, so don't create it
$credentialsPath = $configPath . 'credentials.json';
$client = new Google_Client();
// Matches the "Application Name" you enter during the "Step 1" wizard
$client->setApplicationName( 'App name matching Google Console name' );
$client->setScopes( Google_Service_Sheets::SPREADSHEETS_READONLY );
// You need to go through "Step 1" steps to generate this file: https://developers.google.com/sheets/api/quickstart/php
$client->setAuthConfig( $configPath . 'secret.json' );
$client->setAccessType( 'offline' );
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// This must match the "callback URL" that you enter under "OAuth 2.0 client ID" in the Google APIs console at https://console.developers.google.com/apis/credentials
$client->setRedirectUri( $actual_link );
// We have a stored credentials file, try using the data from there first
if ( file_exists( $credentialsPath ) ) {
$accessToken = json_decode( file_get_contents( $credentialsPath ), true );
}
// No stored credentials found, we'll need to request them with OAuth
else {
// Request authorization from the user
$authUrl = $client->createAuthUrl();
if ( ! isset( $_GET['code'] ) ) {
header( "Location: $authUrl", true, 302 );
exit;
}
// The authorization code is sent to the callback URL as a GET parameter.
// We use this "authorization code" to generate an "access token". The
// "access token" is what's effectively used as a private API key.
$authCode = $_GET['code'];
$accessToken = $client->fetchAccessTokenWithAuthCode( $authCode );
// Create credentials.json if it doesn't already exist (first run)
if ( ! file_exists( dirname( $credentialsPath ) ) ) {
mkdir( dirname( $credentialsPath ), 0700, true );
}
// Save the $accessToken object to the credentials.json file for re-use
file_put_contents( $credentialsPath, json_encode( $accessToken ) );
}
//var_dump( $accessToken ); die();
// Provide client with API access token
$client->setAccessToken( $accessToken );
// If the $accessToken is expired then we'll need to refresh it
if ( $client->isAccessTokenExpired() ) {
$client->fetchAccessTokenWithRefreshToken( $client->getRefreshToken() );
file_put_contents( $credentialsPath, json_encode( $client->getAccessToken() ) );
}
I'm running this code from an actual server that is publicly available, this is not a local machine.