【问题标题】:Account linking and google api帐户链接和 google api
【发布时间】:2018-06-25 12:14:55
【问题描述】:

我已经在简化的身份流程中实现了帐户链接 (https://developers.google.com/actions/identity/oauth2-assertion-flow)

// Get the jwt token from the request
    $token = $this->jwt->parse($body['assertion']);

    if (null === Client::where('id', $body['client_id'])->where('secret', $body['client_secret'])->first()
        && (false === $this->verifySignature($token) || false === $this->validateData($token))
    ) {
        return response()->json(
            [
                'error' => 'invalid_grant',
            ],
            Http::UNAUTHORIZED
        );
    }

    $sub = $token->getClaim('sub');
    $email = $token->getClaim('email');
    $scopes = explode(' ', $body['scope']);

    // Check if the user exists in the database or not
    $userId = User::findIdByGoogleIds($email, $sub);
    \Log::debug($userId);

    // If user doesn't exists and intent is get, ask google to send you the create intent with all user info.
    if (null === $userId && 'get' === $body['intent']) {
        \Log::debug('user not found, ask for a create request');

        return response()->json(
            [
                'error' => 'user_not_found',
            ],
            Http::UNAUTHORIZED
        );

    // If user doesn't exist and we are in intent create, let's create this user in our database.
    } elseif (null === $userId && 'create' === $body['intent']) {
        \Log::debug('user not found, create it');

        // If user exists bug don't have the google profile associated.
        if (null === ($user = User::findByMail($email))) {
            $user = new User();
            $user->password = Hash::make(str_random(8));
            $user->email = $email;
            $user->name = $token->getClaim('name');

            $user->save();
            //Generate a token for the user
            static::generateToken($user, $scopes);
        }

        // Asssociate google profile that user
        $profile = new GoogleProfile();
        $profile->google_id = $sub;
        $user->googleProfiles()->save($profile);

    } elseif (null !== $userId) {
        \Log::debug('google profile already existing');

        $user = User::find($userId->id);
    }

JWT 令牌包含该信息:

{
  "sub": 1234567890,        // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "locale": "en_US"
}

我需要获取用户在他的谷歌个人资料中填写的电话号码(如果有的话)。

所以我正在考虑使用 google + api,所以我正在尝试这个:

    $client = new \Google_Client();
    $client->setClientId('my_client_id');
    $client->setClientSecret('my_client_secret');
    $client->setAccessToken($token->getPayload());
    $plus = new Google_Service_Plus($client);

    $test = $plus->people->get($sub);

client_id 和 secret 已在 https://console.developers.google.com 上创建

回复是:

 {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}
 {"exception":"[object] (Google_Service_Exception(code: 401): {
 \"error\": {
  \"errors\": [
   {
    \"domain\": \"global\",
    \"reason\": \"authError\",
    \"message\": \"Invalid Credentials\",
    \"locationType\": \"header\",
    \"location\": \"Authorization\"
   }
  ],
  \"code\": 401,
  \"message\": \"Invalid Credentials\"
 }
}

因此,据我了解,帐户链接是 OAuth 身份验证,因此它应该向我发送有效的令牌访问权限,我可以将其与 google api 一起使用。 但它告诉我这个令牌是无效的。

我是否遗漏了什么,或者我没有以好的方式做到这一点? 我是否必须再次执行特定于 google api 的新身份验证?

【问题讨论】:

  • 请更新问题以显示您到目前为止所做的事情以及哪些具体不适合您
  • 这不是一个要求提供完整代码示例或教程的网站。请先阅读How to Ask
  • 您能否更新您的问题以包含您当前用于获取用户信息的代码以及您认为可以使用哪些 API 来获取电话号码信息。
  • 我已经用您询问的信息更新了我的初始帖子。

标签: php google-plus actions-on-google dialogflow-es google-profiles-api


【解决方案1】:

你如何做你想做的事情有很多问题。

首先,您在assertion 中获得的令牌是身份令牌,而不是授权令牌。令牌本身不是授权您代表用户执行任何操作的不记名令牌。您指向的关于断言流程的指南说您应该验证令牌,然后使用它从 sub 字段中获取用户的唯一 ID。您应该使用此 ID 来确定用户是否已经在您的系统中进行了身份验证,并使用您为用户提供的 Auth Token 和 Refresh Token。

其次,您可能不需要 Google+ API,因为 Google+ People object 不包含电话号码字段。如果是这样,并且如果您想使用“me”参数获取有关用户的私人信息,则需要在用户登录时请求 https://www.googleapis.com/auth/plus.loginhttps://www.googleapis.com/auth/plus.me auth 范围。

相反,您可能想使用People APIpeople object 包含 phone numbers 可以使用 get 方法检索,但有一些限制:

  • 他们实际上必须设置电话号码,您需要将该字段作为要获取的字段之一请求
  • 如果他们公开了,你应该可以得到它。
  • 如果他们没有将其公开,您需要申请https://www.googleapis.com/auth/user.phonenumbers.read 范围。

【讨论】:

  • 嗨,感谢您对 id 流和 auth 流的评论,我将更改所有这些并以不同的方式处理它。
  • 如果这回答了您的问题,欢迎接受和/或支持它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2020-03-14
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多