Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JSON key instead of P12 in Google Spreadsheet Authentication with PHP?

I am working with Google Spreadsheet in PHP. When I use P12 key it works perfect, but when I use JSON key instead of P12 key while Authenticating with Google Spread Sheet, it is giving

Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Unable to load private key'

Please tell me how to use JSON key while Authenticating with Google Spread Sheet in PHP.

like image 819
Amrinder Singh Avatar asked Nov 05 '15 05:11

Amrinder Singh


2 Answers

Here is the solution I found.

For P12 Key
Normally, we use the following code to generate a token.

public static function getToken()
    {
        $key = file_get_contents( APPLICATION_DIR.'/'.APPLICATION_GOOGLE_CLIENT_KEY_FILE);

        $cred = new Google_Auth_AssertionCredentials(
            APPLICATION_GOOGLE_CLIENT_EMAIL,
            array('https://spreadsheets.google.com/feeds'),
            $key
        );

        $client = new Google_Client();
        $client->setAssertionCredentials($cred);

        if (!$client->getAuth()->isAccessTokenExpired()) {
            return false;
        }
        else {
            $client->getAuth()->refreshTokenWithAssertion($cred);
        }

        $service_token = json_decode($client->getAccessToken());


        return $service_token->access_token;
    }

For JSON Key
But now we don't have P12 key, we have a JSON key, so I just made some changes in the above code, please take a look below:

public static function getToken()
    {

        $key = APPLICATION_DIR.'/'.APPLICATION_GOOGLE_CLIENT_KEY_FILE;
        $data = json_decode(file_get_contents($key));    // here i decoded the json

         if (isset($data->type) && $data->type == 'service_account') {

            $cred = new Google_Auth_AssertionCredentials(
                APPLICATION_GOOGLE_CLIENT_EMAIL,    // it's the client email
                array('https://spreadsheets.google.com/feeds'),   // it's google spreadsheet scope
                $data->private_key         // here is the private key
            );
         }

        $client = new Google_Client();
        $client->setAssertionCredentials($cred);

        if (!$client->getAuth()->isAccessTokenExpired()) {
            return false;
        }
        else {
            $client->getAuth()->refreshTokenWithAssertion($cred);
        }

        $service_token = json_decode($client->getAccessToken());


        return $service_token->access_token;
    }
like image 148
Amrinder Singh Avatar answered Oct 09 '22 03:10

Amrinder Singh


Access token will only be valid 1 hour and is sent as decoded json. So you probably have to decode it first.

$token = json_decode($client->getAccessToken());
$serviceRequest = new DefaultServiceRequest($token->access_token);
ServiceRequestFactory::setInstance($serviceRequest);

Using p12 key should work fine then.

session_start();

define('GOOGLE_CLIENT_ID','');
define('GOOGLE_CLIENT_EMAIL','');
define('GOOGLE_SPREADSHEETS_SCOPE','https://spreadsheets.google.com/feeds');
define('GOOGLE_APPLICATION_NAME','whatever');
define('GOOGLE_KEY_FILE','xxxxxxxxxxxxxx.p12'); // pass for key: notasecret

function getToken()
{
    $client = new Google_Client();
    $client->setApplicationName(GOOGLE_APPLICATION_NAME);
    $client->setClientId(GOOGLE_CLIENT_ID);

    $key = file_get_contents(GOOGLE_KEY_FILE);
    $cred = new Google_Auth_AssertionCredentials(
        GOOGLE_CLIENT_EMAIL,
        array(GOOGLE_SPREADSHEETS_SCOPE),
        $key
    );

    $client->setAssertionCredentials($cred);

    if($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion($cred);
    }

    $service_token = json_decode($client->getAccessToken());
    return $service_token->access_token;
}

require("vendor/autoload.php");

use Google\Spreadsheet\DefaultServiceRequest;
use Google\Spreadsheet\ServiceRequestFactory;

$_SESSION['access_token']=getToken();

$serviceRequest = new Google\Spreadsheet\DefaultServiceRequest($_SESSION['access_token']);
Google\Spreadsheet\ServiceRequestFactory::setInstance($serviceRequest);
$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
$spreadsheetFeed = $spreadsheetService->getSpreadsheets();
like image 39
oshell Avatar answered Oct 09 '22 04:10

oshell