尝试通过PHP Directory API列出我的域组时出错。真正奇怪的是,如果我使用OAuth playground列出组,它可以与这些范围无缝协作:
注意:我没有使用服务帐户执行此操作。我的电子邮件地址具有超级管理员权限,因此我假设在尝试管理群组和群组成员时这应该没问题?我使用Slim 3来处理应用程序的详细信息。我的客户端已初始化并经过身份验证(根据对象上的快速var_dump
),但在尝试执行此操作时出错:
$service = new \Google_Service_Directory($this->client);
var_dump($service->groups->listGroups(["domain" => "example.google.com"])); // placeholder domain for SO
这是我在尝试加载页面时收到的错误,因此我可以列出这些组:
#0 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Http/REST.php(62): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client))
#1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request))
#2 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Task/Runner.php(174): call_user_func_array(Array, Array)
#3 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Http/REST.php(46): Google_Task_Runner->run()
#4 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Client.php(593): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#5 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Service/Resource.php(240): Google_Client->execute(Object(Google_Http_Request))
#6 /Applications/MAMP/htdocs/aslists/vendor/google/apiclient/src/Google/Service/Directory.php(2122): Google_Service_Resource->call('list', Array, 'Google_Service_...')
#7 /Applications/MAMP/htdocs/aslists/src/controllers/DashboardController.php(23): Google_Service_Directory_Groups_Resource->listGroups(Array)
#8 [internal function]: a_s\controllers\DashboardController->index(Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
...
#18 {main}
为什么使用PHP API查询失败,但在OAuth游乐场成功?
我提前道歉,这将包含很多代码......
我花了一些时间来修改PHP Quickstart示例,其中我的client_secret.json
文件被加载到应用程序中,如下所示:
$this->client->setAuthConfigFile('/path/to/client_secret.json');
$credentialsPath = $this->expandHomeDirectory('/path/to/.credentials/admin-directory_v1-php-quickstart.json');
if(file_exists($credentialsPath)) {
$accessToken = file_get_contents($credentialsPath);
}
if(isset($accessToken)) {
$this->client->setAccessToken($accessToken);
}
if($this->client->isAccessTokenExpired()) {
$this->client->refreshToken($this->client->getRefreshToken());
file_put_contents($credentialsPath, $this->client->getAccessToken());
}
$this->service = new \Google_Service_Directory($this->client);
如果我使用这种方法,它与我的应用程序完美配合 - 非常奇怪。我在此方法之间进行了额外的调查,并使用Google登录该应用程序,我无法找到任何结论。鉴于此,如果我使用谷歌登录,它应工作,但它仍然没有。
以下是我如何初始化客户端:
class GoogleController extends Controller {
private static $APP_NAME = "Lists Manager";
private static $CLIENT_ID = "...";
private static $CLIENT_SECRET = "...";
private static $REDIRECT_URI = "postmessage";
private static $ACCESS_TYPE = "offline";
private static $scopes = [
\Google_Service_Oauth2::USERINFO_PROFILE,
\Google_Service_Oauth2::USERINFO_EMAIL,
\Google_Service_Directory::ADMIN_DIRECTORY_GROUP,
\Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER,
\Google_Service_Directory::ADMIN_DIRECTORY_USER
];
protected $client;
public function __construct($container) {
parent::__construct($container);
$this->client = new \Google_Client();
$this->client->setApplicationName(self::$APP_NAME);
$this->client->setClientId(self::$CLIENT_ID);
$this->client->setClientSecret(self::$CLIENT_SECRET);
$this->client->setRedirectUri(self::$REDIRECT_URI);
$this->client->setScopes(self::$scopes);
$this->client->setAccessType(self::$ACCESS_TYPE);
}
}
从这里开始,我有另一个扩展GoogleController
的控制器,它包含一个ajax端点(即它发布的访问码所在的位置)。代码如下所示:
class LoginController extends GoogleController {
public function __construct($container) {
parent::__construct($container);
}
public function login($request, $response) {
if($this->client->isAccessTokenExpired()) {
unset($_SESSION[GoogleController::AS_PERSISTENT_CLIENT_OBJECT]);
$this->tokens = $this->client->authenticate($request->getBody()->getContents());
// $this->client->setAccessToken($this->token); // Not sure if I need to do this. Either way, I still get the exception
}
$_SESSION[GoogleController::AS_PERSISTENT_CLIENT_OBJECT] = serialize($this->client);
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write($this->generateJsonSuccess('dashboard'));
}
}