【发布时间】:2021-12-20 05:47:28
【问题描述】:
我正在尝试为我的 Google Drive 帐户设置推送通知到 PHP webhook 端点。
首先,我按照这里的说明进行操作:
https://developers.google.com/drive/api/v3/push
这导致我验证了我的域并在 Search Console 中注册了它。一切似乎都很好。在这个阶段,我收到了一个包含以下数据的 JSON 文件:
{
"type": "service_account",
"project_id": "mywebapp",
"private_key_id": "myprivatekey",
"private_key": "-----BEGIN PRIVATE KEY-----somelongkey-----END PRIVATE KEY-----\n",
"client_email": "somemeail@appspot.gserviceaccount.com",
"client_id": "someclientid",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/mywebapp%40appspot.gserviceaccount.com"
}
然后为了设置watch channel,我有一个PHP脚本
$service_account_email = "myserviceaccount@mywebapp.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----somelongkey-----\n";
$uid = 'someid';
$is_premium_account = false;
$now_seconds = time();
$payload = array(
"iss" => $service_account_email,
"sub" => $service_account_email,
"aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat" => $now_seconds,
"exp" => $now_seconds+(60*60), // Maximum expiration time is one hour
"uid" => $uid,
"claims" => array(
"premium_account" => $is_premium_account
)
);
$token = JWT::encode($payload, $private_key, "RS256");
// now set up watch channel
$body = [
'id' => uniqid(),
'type' => 'web_hook',
'address' => 'https://mywebhookendpoint'
];
$client = new \GuzzleHttp\Client();
$result = $client->post('https://www.googleapis.com/drive/v3/changes/watch', [
'headers' => [ 'Content-Type' => 'application/json', "Authorization: Bearer ".$token ],
'base_uri' => "https://www.googleapis.com/drive/v3/changes/watch",
'body' => json_encode($body)
]);
当我这样做时,我得到
Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `POST https://www.googleapis.com/drive/v3/changes/watch` resulted in a `401 Unauthorized` response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials" (truncated...)
当我在 PHPStorm 中调试调用时,我看到创建了一个令牌,并且它从当前时间开始过期一小时。总的来说,一切都“看起来”很好。
我怀疑我从根本上采取了错误的方法,这不会让我感到惊讶,因为我以前从未尝试过,而且 Google 文档似乎对身份验证难题的所有不同部分如何组合在一起非常神秘,尤其是当/where 需要 Oauth,服务帐户何时/何地就足够了,JWT 令牌在何处/何时起作用。
如何克服上述错误?
【问题讨论】:
-
为什么不用google api php客户端库?
-
最终还是这样做了(我目前的方法在下面的答案中)
标签: php google-drive-api