How to get OAuth2 access token with Google API PHP

2019-04-13 09:06发布

I'm trying to get an OAuth access token to import some data into the fusion table. I'm trying to use the Google API PHP client. I have created a service account for that purpose, and am using the code, mostly from the serviceAccount example:

function access_token()
{
    $client = new Google_Client();
    $client->setAuthClass ('Google_OAuth2');
    // ^ Don't know if this line is required,
    // ^ but it fails just as well without it.
    $client->setApplicationName ('Mysite.dom.ain');
    $client->setAssertionCredentials (new Google_AssertionCredentials
        (   'MANY-NUMBERS-LETTERS-DASHES@developer.gserviceaccount.com',
            array ('https://www.googleapis.com/auth/fusiontables'),
            file_get_contents ('path/to/my/privatekey.p12') ));
    $client->setClientId ('NUMBERS-LETTERS-DASHES.apps.googleusercontent.com');
    $client->authenticate();
    // ^ Also fails equally good with and without this line.
    return $client->getAccessToken();
}

A little debug output shows that $client->authenticate() returns true, but $client->getAcessToken() returns null. No exceptions are thrown. I have the feeling I'm doing something fundamentally wrong. If so, please forgive my stupidity and point me in the right direction.

2条回答
劫难
2楼-- · 2019-04-13 09:23

I think all you did was correct, now you have two options left:

  • Use your $client to make a service call with something like that
    $service = new Google_FusiontablesService($client);
    $selectQuery = "select * from 1AwxQ46kfmPoYoq38e5CopJOWkCo_9GUU_ucD6zI";
    $service->query->sql($selectQuery)
  • Or call the internal function refreshTokenWithAssertion() in order to get your token:
    $client::$auth->refreshTokenWithAssertion();
    $token = $client->getAccessToken(); //this should work now

For both cases I have examples in my GitHub Repo.

查看更多
Explosion°爆炸
3楼-- · 2019-04-13 09:32

You don't need the authenticate() call, but you'll need to call refreshTokenWithAssertion() to refresh the underlying access token. If you are using the client library to make signed requests, it will lazily make this call for you if underlying access token has expired.

The API requests to refresh the access_token are expensive, and have a low quota, so you'll want to cache the access_token.

// Set your client id, service account name, and the path to your private key.
// For more information about obtaining these keys, visit:
// https://developers.google.com/console/help/#service_accounts
const CLIENT_ID = 'INSERT_YOUR_CLIENT_ID';
const SERVICE_ACCOUNT_NAME = 'INSERT_YOUR_SERVICE_ACCOUNT_NAME';

// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = '/super/secret/path/to/key.p12';

$client = new Google_Client();
$client->setApplicationName("Google FusionTable Sample");

// Set your cached access token. Remember to store the token in a real database instead of $_SESSION.
session_start();
if (isset($_SESSION['token'])) {
 $client->setAccessToken($_SESSION['token']);
}

$key = file_get_contents(KEY_FILE);
$client->setAssertionCredentials(new Google_AssertionCredentials(
    SERVICE_ACCOUNT_NAME,
    array('https://www.googleapis.com/auth/fusiontables'),
    $key)
);

$client->setClientId(CLIENT_ID);

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

// Get the json encoded access token.
$token = $client->getAccessToken();
查看更多
登录 后发表回答