我在使用PHP实施Google Admin SDK时遇到问题。它总是给出错误
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST
https://www.googleapis.com/admin/directory/v1/users: (403) Not Authorized to access this
resource/api' in ..\google-api-php-client\src\Google\Http\REST.php on line 79
这是我的代码:
<?php
session_start();
/* * **********************************************
Make an API request authenticated with a service
account.
* ********************************************** */
set_include_path("google-api-php-client/src" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Service/Directory.php';
/* * **********************************************
ATTENTION: Fill in these values! You can get
them by creating a new Service Account in the
API console. Be sure to store the key file
somewhere you can get to it - though in real
operations you'd want to make sure it wasn't
accessible from the webserver!
The name is the email address value provided
as part of the service account (not your
address!)
Make sure the Books API is enabled on this
account as well, or the call will fail.
* ********************************************** */
$client_id = 'my_client_id'; //Client ID
$service_account_name = 'email'; //Email Address
$key_file_location = 'key.p12'; //key.p12
if ($client_id == '<YOUR_CLIENT_ID>' || !strlen($service_account_name) || !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
}
$client = new Google_Client();
$client->setApplicationName("appname");
$service = new Google_Service_Directory($client);
/* * **********************************************
If we have an access token, we can carry on.
Otherwise, we'll get one with the help of an
assertion credential. In other examples the list
of scopes was managed by the Client, but here
we have to list them manually. We also supply
the service account
* ********************************************** */
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array('https://www.googleapis.com/auth/admin.directory.user'), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
/* * **********************************************
We're just going to make the same call as in the
simple query as an example.
* ********************************************** */
$familyName = filter_input(INPUT_GET, 'familyname');
$givenName = filter_input(INPUT_GET, 'givenname');
$password = filter_input(INPUT_GET, 'password');
$primaryEmail = filter_input(INPUT_GET, 'email');
$user = new Google_Service_Directory_User();
$name = new Google_Service_Directory_UserName();
$name->setFamilyName($familyName);
$name->setGivenName($givenName);
$user->setName($name);
$user->setHashFunction("MD5");
$user->setPrimaryEmail($primaryEmail);
$user->setPassword(hash("md5", $password));
$result = $service->users->insert($user);
没有文档,我对此错误非常困惑。
答案 0 :(得分:2)
我遇到了类似的问题,直到我在凭据对象上设置了“sub”帐户,该帐户是您要执行API操作的管理用户的电子邮件地址。
因此,在您的域的Google Apps管理员中,我假设您已创建了一个用户并将其添加到具有API访问权限的管理员角色中吗?在上面的代码中,您只需添加(当然使用正确的电子邮件地址):
$cred->sub = "adminuser@domain.com";
在此之前添加:
$client->setAssertionCredentials($cred);
我为其他人提供了一个完整的示例,您也可以参考:https://gist.github.com/fillup/9fbf5ff35b337b27762a
答案 1 :(得分:1)
我遇到了类似的问题,但通过浏览此博客找到了解决方法
http://michaelseiler.net/2014/12/16/google-admin-sdk-api-with-php/
假设您已在管理控制台上完成了所有必要的设置(即委派域名权限),那么请特别注意该行
`$cred = new Google_Auth_AssertionCredentials($service_account_name, array('https://www.googleapis.com/auth/admin.directory.user'), $key);`
这应该是:
`$user_to_impersonate = 'adminaccount@example.com';$scopes =array('https://www.googleapis.com/auth/admin.directory.user');$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
$scopes,
$key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$user_to_impersonate);`
我改变了它并且繁荣......
答案 2 :(得分:0)
我想我在尝试查询用户时收到此错误。
在创建断言的JWT_CLAIM部分期间,您必须指定您的服务帐户可以模拟的域管理员帐户...我认为这部分文档很少。
我不确切知道谷歌php库是如何做到的,但我没有在你的代码中看到你指定该帐户电子邮件地址的任何地方。如果您查看了oauth2文档,那么在jwt_claim中,还有一个&#34;附加声明&#34;小节说:
要获取授予应用程序委派的资源访问权限的访问令牌,请在JWT声明集中包含用户的电子邮件地址作为子字段的值。
在我甚至可以查询directory.users API之前,我必须在创建断言时包含该管理员电子邮件帐户。
我道歉,如果这不是有用的,但我不使用PHP的库,我建立自己的(用PHP)。