问题
- Google Apps for Business linked to Apps Engine account
- Cloud Console -> Registered Apps -> {name} -> Web Application -> OAuth 2.0 ClientID
- Cloud Console -> Admin API (On)
- Google Apps Console -> Security -> API Access (checked)
- " -> " -> 3rd party OAuth -> API Clients ({ClientID}.apps.googleusercontent.com)
- " -> " -> " -> API Scopes (https://www.googleapis.com/auth/admin.directory.user)
Here is what I have so far,
require_once 'google/appengine/api/app_identity/AppIdentityService.php';
use \google\appengine\api\app_identity\AppIdentityService;
function setAuthHeader() {
$access_token =AppIdentityService::getAccessToken("https://www.googleapis.com/auth/admin.directory.user");
return [ sprintf("Authorization: OAuth %s", $access_token["access_token"]) ];
}
$get_contacts_url = "https://www.googleapis.com/admin/directory/v1/users?customer=my_customer";
$headers = implode("\n\r", setAuthHeader());
$opts =
array("http" =>
["http" => ["header" => $headers ]]
);
$context = stream_context_create( $opts );
$response = file_get_contents( $get_contacts_url, false, $context );
print_r ($response);
The "access_token" comes through just fine, but $response returns,
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } }
On the Users: List example at the bottom of the page, they show the "Get" request as follows,
GET https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&key={YOUR_API_KEY}
What is {YOUR_API_KEY}? I've tried every Cloud Console and Google Apps API with no luck.
I'm I going about this completely wrong, should I be using a completely different approach? I've been struggling with this for over a week and would love any sort of response. Thanks
回答1:
I think the easiest way to accomplish this is to use the PHP client library, https://github.com/google/google-api-php-client/, provided by Google, it does a good job of dealing with the auth stuff for you. It gets really tricky with the JWT stuff if you try to do it yourself. I just put together an example for you of doing this, https://gist.github.com/fillup/9fbf5ff35b337b27762a. I tested it with my own Google Apps account and verified it works, let me know if you have problems with it.
Edit: Adding code example here for ease:
<?php
/**
* Easiest to use composer to install google-api-php-client and generate autoloader
* If you dont want to use composer you can manually include any needed files
*/
include_once 'vendor/autoload.php';
/**
* Client ID from https://console.developers.google.com/
* Must be added in Google Apps Admin console under Security -> Advanced -> Manage API client access
* Requires scope https://www.googleapis.com/auth/admin.directory.user or
* https://www.googleapis.com/auth/admin.directory.user.readonly
*/
$clientId = 'somelongstring.apps.googleusercontent.com';
/**
* Service Account Name or "Email Address" as reported on https://console.developers.google.com/
*/
$serviceAccountName = 'somelongstring@developer.gserviceaccount.com';
/**
* Email address for admin user that should be used to perform API actions
* Needs to be created via Google Apps Admin interface and be added to an admin role
* that has permissions for Admin APIs for Users
*/
$delegatedAdmin = 'delegated-admin@domain.com';
/**
* This is the .p12 file the Google Developer Console gave you for your app
*/
$keyFile = 'file.p12';
/**
* Some name you want to use for your app to report to Google with calls, I assume
* it is used in logging or something
*/
$appName = 'Example App';
/**
* Array of scopes you need for whatever actions you want to perform
* See https://developers.google.com/admin-sdk/directory/v1/guides/authorizing
*/
$scopes = array(
'https://www.googleapis.com/auth/admin.directory.user'
);
/**
* Create AssertionCredentails object for use with Google_Client
*/
$creds = new Google_Auth_AssertionCredentials(
$serviceAccountName,
$scopes,
file_get_contents($keyFile)
);
/**
* This piece is critical, API requests must be used with sub account identifying the
* delegated admin that these requests are to be processed as
*/
$creds->sub = $delegatedAdmin;
/**
* Create Google_Client for making API calls with
*/
$client = new Google_Client();
$client->setApplicationName($appName);
$client->setClientId($clientId);
$client->setAssertionCredentials($creds);
/**
* Get an instance of the Directory object for making Directory API related calls
*/
$dir = new Google_Service_Directory($client);
/**
* Get specific user example
*/
//$account = $dir->users->get('example@domain.com');
//print_r($account);
/**
* Get list of users example
* In my testing you must include a domain, even though docs say it is optional
* I was getting an error 400 without it
*/
$list = $dir->users->listUsers(array('domain' => 'domain.com', 'maxResults' => 100));
print_r($list);
回答2:
In short: you are over-simplifying OAuth2.
It's not as easy as sending over a key as a HTTP GET parameter to get the data.
I'm sure that you have read this, but you need to understand the OAuth2 web flow and how a client library can leverage the usage for you. You should be requiring this file in order to use the Directory API.
回答3:
Are you using the latest PHP library or the deprecated one? For the latest BETA PHP library, this is the part of the code that is related with the authentication section.
set_include_path("google-api-php-client-master/src/" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Auth/OAuth2.php';
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
// Replace this with the email address from the client.
$clientEmail,
// Replace this with the scopes you are requesting.
array(SCOPES),
$key
);
$cred->sub = ""; //admin email
$client->setAssertionCredentials($cred);
try {
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
来源:https://stackoverflow.com/questions/20477294/admin-sdk-directory-api-users-list-any-php-examples-on-how-to-do-this