2017-05-10 8 views
6

Google OAuth経由でログインしたユーザーのプロフィール情報をリクエストしようとしています。私の要求は適切に形成されていますが、正常にログインしますが、PHPで次のリクエストを行うと、リクエストマスクが空になることはありません。有効なパスは...Google People API「リクエストマスクは空ではありません」

しかし、Google People API people.get documentationから、要求マスク値はオプションであり、渡されない場合はwill return all values except for people.connections.listであることが明らかです。ここに私のコードは次のとおりです。ここで

// The entire OAuth process works up until this point... 
// create the service 
$service = new Google_Service_People($this->client); 

try { 
    $results = $service->people->get('people/me'); 
} catch(\Exception $exception) { 
    echo $exception->getMessage(); 
    exit; 
} 

は、私はこのエラーから入手例外メッセージです:

{ "error": { "code": 400, "message": "Request mask can not be empty. Valid paths are: [person.addresses, person.age_ranges, person.biographies, person.birthdays, person.bragging_rights, person.cover_photos, person.email_addresses, person.events, person.genders, person.im_clients, person.interests, person.locales, person.memberships, person.metadata, person.names, person.nicknames, person.occupations, person.organizations, person.phone_numbers, person.photos, person.relations, person.relationship_interests, person.relationship_statuses, person.residences, person.skills, person.taglines, person.urls].", "errors": [ { "message": "Request mask can not be empty. Valid paths are: [person.addresses, person.age_ranges, person.biographies, person.birthdays, person.bragging_rights, person.cover_photos, person.email_addresses, person.events, person.genders, person.im_clients, person.interests, person.locales, person.memberships, person.metadata, person.names, person.nicknames, person.occupations, person.organizations, person.phone_numbers, person.photos, person.relations, person.relationship_interests, person.relationship_statuses, person.residences, person.skills, person.taglines, person.urls].", "domain": "global", "reason": "badRequest" } ], "status": "INVALID_ARGUMENT" } }

誰も私を助けることはできますか?私は〜以来、囲碁ライブラリと同じエラーが出始めIllegal string offset 'type'

+0

最新のPHPライブラリを使用していますか?そうでない場合は、最新バージョンにアップデートしてください。 – abraham

+1

同じエラーが発生していますが、javascriptとウェブページがあります。私は前回の作業から何も変えていないと思う。これはちょうど始まったあなたのための新しい問題ですか、あるいはあなたはこれを実装しようとしましたか? – kirypto

+1

今日からGoライブラリで同じエラーが発生しました。 (私は数週間、私のコードに触れていません。)最近何かが変わったのでしょうか? – gonbe

答えて

4

私は回避策を見つけました。 Peopleの代わりにPlusサービスから部分的なユーザープロファイル情報を要求することができました。なぜこれが変わったように見えるのか、私は、GoogleがAPIの内部ロジックを修正し、ドキュメントを更新していないことに気付きました。 (この執筆時点では、GoogleのPHP OAuthライブラリはベータ版です)。

私の場合、私が実際に行ったことは、ユーザーのユーザー名と電子メールアドレスを取得することでした。 Peopleサービスを使用してプロファイルリクエストを行う代わりに、代わりにPlusサービスを使用し、電子メールアドレスを取得するための追加の範囲を求めました。ここに私のPHP実装の全体があります。取得するカップルの追加要求に成功し、私が代わりにプラスサービスからmeを要求しています認証するのではなく、人々のサービスからpeople/meを要求した後

Google_Service_Plus::USERINFO_PROFILE, Google_Service_People::USERINFO_PROFILE, Google_Service_People::USERINFO_EMAIL

、:私はコンストラクタで要求しています3つのスコープに注意してください。残りの情報:

$plus = new Google_Service_Plus($this->client); 

try { 
    $plus_results = $plus->people->get('me'); 
} catch(\Exception $exception) { 
    echo $exception->getMessage(); 
    exit; 
} 

<?php 
 

 
namespace App\Auth; 
 
require_once '/var/www/html/oauth/vendor/google/apiclient-services/src/Google/Service/People.php'; 
 
require_once '/var/www/html/oauth/vendor/google/apiclient-services/src/Google/Service/Plus.php'; 
 
require_once '/var/www/html/oauth/vendor/google/apiclient/src/Google/Client.php'; 
 
require_once 'Session.php'; 
 
use Google_Client; 
 
use Google_Service_People; 
 
use Google_Service_Plus; 
 
use App\Auth\Session; 
 

 
/** 
 
* This class performs a basic oauth authentication 
 
* using Google sign in and upon calling the handle_auth 
 
* method, retrieves the user's profile and sets session 
 
* variables for use throughout an application. 
 
*/ 
 
class GoogleAuth { 
 

 
    private static $DOMAIN = 'google'; 
 

 
    /** 
 
    * Google auth client 
 
    * @var Google_Client 
 
    */ 
 
    public $client; 
 

 
    /** 
 
    * Config json filepath 
 
    * @var String 
 
    */ 
 
    public $config_json; 
 

 
    /** 
 
    * The URI to redirect to after succesful oauth 
 
    * @var String 
 
    */ 
 
    public $redirect_uri; 
 

 
    /** 
 
    * The authorization url 
 
    * @var String 
 
    */ 
 
    public $auth_url; 
 

 
    /** 
 
    * Logout url to redirect to after logout 
 
    * @var String 
 
    */ 
 
    public $logout_url; 
 

 
    /** 
 
    * The name of the application as listed in the Google 
 
    * app Dashboard. 
 
    * @var String 
 
    */ 
 
    public $application_name; 
 

 
    /** 
 
    * The developer hash key available in the Google 
 
    * App Credentials dashboard. 
 
    * @var String 
 
    */ 
 
    public $developer_key; 
 

 
    /** 
 
    * Scopes to request in the oauth request. 
 
    * @var [type] 
 
    */ 
 
    public $scope; 
 

 
    /** 
 
    * Url to redirect to upon successful authentication 
 
    * @var String 
 
    */ 
 
    public $auth_success_url; 
 

 
    public function __construct($config) { 
 
    // Eventually we can extend the scope to handle different 
 
    // values or multiple values. For now, this class only 
 
    // supports user profile information. 
 
    $config['scope'] = array(
 
     Google_Service_Plus::USERINFO_PROFILE, 
 
     Google_Service_People::USERINFO_PROFILE, 
 
     Google_Service_People::USERINFO_EMAIL 
 
    ); 
 

 
    $this->init($config); 
 
    } 
 

 
    private function init($config) { 
 
    
 
    if(!isset($config)) { 
 
     throw new \Exception('Config is not valid.'); 
 
    } 
 
    if(!isset($config['config_json'])) { 
 
     throw new \Exception('Path to config json is invalid.'); 
 
    } 
 
    if(!file_exists($config['config_json'])) { 
 
     throw new \Exception('Config JSON file could not be found: ' . $config['config_json']); 
 
    } 
 
    if(!isset($config['application_name'])) { 
 
     throw new \Exception('Application name is invalid.'); 
 
    } 
 
    if(!isset($config['developer_key'])) { 
 
     throw new \Exception('Developer Key is invalid.'); 
 
    } 
 
    if(!isset($config['scope'])) { 
 
     throw new \Exception('Scope is invalid.'); 
 
    } 
 
    if(!isset($config['redirect_uri'])) { 
 
     throw new \Exception('Redirect URL is invalid.'); 
 
    } 
 
    if(!isset($config['logout_url'])) { 
 
     throw new \Exception('Logout URL is invalid.'); 
 
    } 
 

 
    $this->client = new Google_Client(); 
 
    $this->config_json = $config['config_json']; 
 
    $this->redirect_uri = $config['redirect_uri']; 
 
    $this->application_name = $config['application_name']; 
 
    $this->developer_key = $config['developer_key']; 
 
    $this->scope = $config['scope']; 
 
    $this->logout_url = $config['logout_url']; 
 

 
    // Let the session know where we want to go on logout. 
 
    Session::set_logout_url($this->logout_url, self::$DOMAIN); 
 

 
    $this->client->setAuthConfig($this->config_json); 
 

 
    foreach($this->scope as $scope) { 
 
     $this->client->addScope($scope); 
 
    } 
 
    
 
    $this->client->setApplicationName($this->application_name); 
 
    $this->client->setDeveloperKey($this->developer_key); 
 
    $this->client->setRedirectUri($this->redirect_uri); 
 
    $this->client->setPrompt('select_account'); 
 
    $this->auth_url = $this->client->createAuthUrl(); 
 
    } 
 

 
    public static function auth_failure(\Exception $exception) { 
 
    return Session::auth_failure(
 
     $exception->getMessage(), 
 
     self::$DOMAIN 
 
    ); 
 
    } 
 

 
    public static function logout() { 
 
    return Session::logout(self::$DOMAIN); 
 
    } 
 

 
    public function authenticate($request) { 
 
    if (!$request->has('code')) { 
 

 
     // User is unauthenticated, send them through the auth process 
 
     return filter_var($this->auth_url, FILTER_SANITIZE_URL); 
 

 
    } else { 
 
     $code = $request->input('code'); 
 

 
     // process the code received from the auth process 
 
     $token_response = $this->process_code($code); 
 
     
 
     // Ensure the token response is valid 
 
     Validator::token_response($token_response); 
 
     
 
     // Process and retrieve the access token 
 
     $raw_token = $this->process_token_response($token_response); 
 

 
     if(isset($raw_token)) { 
 
     // Handle the token and process the id_token 
 
     $this->handle_id_token($raw_token); 
 
      
 
     // Create the people service and make requests 
 
     return $this->make_profile_request(); 
 

 
     } else { 
 
     throw new \Exception('Failed to retrieve the access token'); 
 
     } 
 
    } 
 
    } 
 

 
    private function process_code($code) { 
 
    // grab the code from the URL and generate an access token 
 
    $response = $this->client->fetchAccessTokenWithAuthCode($code); 
 

 
    if(!is_array($response)) { 
 
     throw new \Exception('Token response was invalid.'); 
 
    } 
 

 
    return $response; 
 
    } 
 

 
    private function process_token_response($token_response) { 
 
    $this->client->setAccessToken($token_response); 
 
    return $this->client->getAccessToken(); 
 
    } 
 

 
    private function handle_id_token($token) { 
 

 
    $id_token = null; 
 

 
    try { 
 
     $id_token = $this->client->verifyIdToken($token['id_token']); 
 
    } catch(\Exception $exception) { 
 
     // clear the access token to disable any 
 
     // approved permissions for the user's account 
 
     $this->client->revokeToken(); 
 
     
 
     throw new \Exception('Google Login failed'); 
 
    } 
 

 
    if(!$id_token) { 
 
     throw new \Exception('Id Token is null or undefined'); 
 
    } 
 

 
    // grab the domain from the id_token 
 
    $email = $id_token['email']; 
 

 
    // Stuff it into the session 
 
    Session::set_email($email, self::$DOMAIN); 
 
    } 
 

 
    private function make_profile_request() { 
 
    // create the service 
 
    $plus = new Google_Service_Plus($this->client); 
 

 
    try { 
 
     $plus_results = $plus->people->get('me'); 
 
    } catch(\Exception $exception) { 
 
     echo $exception->getMessage(); 
 
     exit; 
 
    } 
 
    
 
    if(!$plus_results) { 
 
     throw new \Exception('No matching profile results.'); 
 
    } 
 

 
    // Get the user's display name 
 
    $username = $plus_results->getDisplayName(); 
 

 
    // Stuff it into the session 
 
    Session::set_username($username, self::$DOMAIN); 
 
     
 
    // Login. Session handles the redirect 
 
    return Session::login(
 
     $username, 
 
     Session::get_email(self::$DOMAIN), 
 
     self::$DOMAIN 
 
    ); 
 
    } 
 
} 
 
?>

+1

ソリューションDannyを投稿してくれてありがとう。私が上で述べたように、私はjavascript APIを使用していますが、あなたのソリューションは私を私に導きます。もし誰かがこれを読んで知りたければ、私は '人の人の人の人の人の人の人の人の人の人の人の人の人の人の人の人の人のものから'私はgapi.client.plus.people.get({userId: 'me'})にgapi.client.people.people.get({resourceName: "people/me"}) })。then(...) ' – kirypto

+0

驚くばかりです、それはあなたのためにもうまくいってうれしいです! –

3


アップデート1:

私は要求マスクのためのいくつかの値を渡ししようと、$service->people->get('people/me', array("person.names"));私は例外メッセージを取得5月11日。 includeFieldのない私のコードは、Google APIが変更される前に正常に動作していました。フィールドはオプションでした。

Googleドキュメントでは、「includeField」は必須フィールドです。私は他の場所で発表を見つけることができません。

https://developers.google.com/people/api/rest/v1/RequestMask

includeField

Required. Comma-separated list of person fields to be included in the response. Each path should start with person.: for example, person.names or person.photos.

Last updated May 19, 2017

私golangケースを解決するために、私はpeople.getの呼び出しを行う前に、RequestMaskIncludeField場を提供しなければなりませんでした。

people_get_call := peopleService.People.Get("people/me").RequestMaskIncludeField("person.addresses,person.age_ranges,person.biographies,person.birthdays,person.bragging_rights,person.cover_photos,person.email_addresses,person.events,person.genders,person.im_clients,person.interests,person.locales,person.memberships,person.metadata,person.names,person.nicknames,person.occupations,person.organizations,person.phone_numbers,person.photos,person.relations,person.relationship_interests,person.relationship_statuses,person.residences,person.skills,person.taglines,person.urls") 
google_account, err := people_get_call.Do() 
5

あまりにも遅いですが、これは他の誰かにとって役に立ちます。@gonbeは指摘のように、APIコール

$optParams = array('requestMask.includeField'=>'person.names'); 
0

でrequestMaskを追加するための第二引数として配列以下

使用、RequestMaskIncludeFieldが必要ですが、いくつかの時間のためにそれはあるされませんでした。最新のjava lib(現在のrev139-1.22.0)では、リクエストにsetRequestMaskIncludeField()メソッドを追加するだけで済みます。

peopleService.people().get("people/me").setRequestMaskIncludeField("person.email_addresses").execute(); 
関連する問題