Google Admin SDK PHP无法创建用户。未经授权

时间:2014-09-25 12:04:05

标签: php google-admin-sdk

我在使用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);

没有文档,我对此错误非常困惑。

3 个答案:

答案 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)。