Google API客户端PHP访问令牌不起作用

时间:2018-07-27 10:50:32

标签: php api google-api-client

我正在使用“ google api客户端php”来使用服务帐户json基本密钥文件获取访问令牌。但是我正在获取访问令牌为空。我的示例代码是

$client = new \Google_Client();
$client->setApplicationName('My App');
putenv('GOOGLE_APPLICATION_CREDENTIALS=path-to-the-key.json');
$client->useApplicationDefaultCredentials();
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$client->authorize();
$token = $client->getAccessToken();
echo $token; // null

2 个答案:

答案 0 :(得分:0)

我使用了类似类型的客户端来获取访问令牌,但这是用于Google工作表的。 就像那样。所以我在这里分享我的Google表格代码段。

<?php
if (!function_exists('curl_reset'))
{
    function curl_reset(&$ch)
    {
        $ch = curl_init();
    }
}

require_once __DIR__ . '/goog/vendor/autoload.php';

define('APPLICATION_NAME', 'Google Sheets API PHP Quickstart');
define('CREDENTIALS_PATH', __DIR__ . '/sheets.googleapis.com-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-php-quickstart.json
define('SCOPES', implode(' ', array(
  Google_Service_Sheets::SPREADSHEETS)
));

if (php_sapi_name() != 'cli') {
  throw new Exception('This application must be run on the command line.');
}

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient() {
  $client = new Google_Client();
  $client->setApplicationName(APPLICATION_NAME);
  $client->setScopes(SCOPES);
  $client->setAuthConfig(CLIENT_SECRET_PATH);
  $client->setAccessType('offline');

  // Load previously authorized credentials from a file.
  $credentialsPath = CREDENTIALS_PATH;
  if (file_exists($credentialsPath)) {
    $accessToken = json_decode(file_get_contents($credentialsPath), true);
  } 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);

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, json_encode($accessToken));
    printf("Credentials saved to %s\n", $credentialsPath);
  }
  $client->setAccessToken($accessToken);

  // Refresh the token if it's expired.
  if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
  }
  return $client;
}

因此,当您在命令行中的php脚本中调用getClient函数时,它将生成一个链接以在浏览器中验证用户,此后它将提供您必须在命令行中放置的代码。然后它将生成访问令牌,以后可以重用。

答案 1 :(得分:0)

通过从Google文档开发自己的php代码解决了我的问题。我使用Guzzle HTTP Client使用符号JWT有效负载来获取访问令牌。 Here is the doc

我的实现:

 public static function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

public static function getJwtAssertion($private_key_file)
{

    $json_file = file_get_contents($private_key_file);
    $info = json_decode($json_file);
    $private_key = $info->{'private_key'};

    //{Base64url encoded JSON header}
    $jwtHeader = self::base64url_encode(json_encode(array(
        "alg" => "RS256",
        "typ" => "JWT"
    )));

    //{Base64url encoded JSON claim set}
    $now = time();
    $jwtClaim = self::base64url_encode(json_encode(array(
        "iss" => $info->{'client_email'},
        "scope" => "https://www.googleapis.com/auth/analytics.readonly",
        "aud" => "https://www.googleapis.com/oauth2/v4/token",
        "exp" => $now + 3600,
        "iat" => $now
    )));

    $data = $jwtHeader.".".$jwtClaim;

    // Signature
    $Sig = '';
    openssl_sign($data,$Sig,$private_key,'SHA256');
    $jwtSign = self::base64url_encode($Sig);

    //{Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature}
    $jwtAssertion = $data.".".$jwtSign;
    return $jwtAssertion;
}

public static function getGoogleAccessToken($private_key_file)
{

    $result = [
        'success' => false,
        'message' => '',
        'token' => null
    ];

    if (Cache::has('google_token')) {
        $result['token'] = Cache::get('google_token');
        $result['success'] = true;
        return $result;
    }

    if(!file_exists($private_key_file)){
        $result['message'] = 'Google json key file missing!';
        return $result;

    }

    $jwtAssertion = self::getJwtAssertion($private_key_file);

    try {

        $client = new Client([
            'base_uri' => 'https://www.googleapis.com',
        ]);
        $payload = [
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwtAssertion
        ];

        $response = $client->request('POST', 'oauth2/v4/token', [
            'form_params' => $payload
        ]);

        $data = json_decode($response->getBody());
        $result['token'] = $data->access_token;
        $result['success'] = true;

        $expiresAt = now()->addMinutes(58);
        Cache::put('google_token', $result['token'], $expiresAt);

    } catch (RequestException $e) {
          $result['message'] = $e->getMessage();
    }


    return $result;

}

现在叫它:

$googleToken = getGoogleAccessToken($KEY_FILE_LOCATION);