Ссылка на аккаунт и Google API - PullRequest
0 голосов
/ 25 июня 2018

Я реализовал привязку аккаунта в упорядоченном потоке идентификации (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 (если он есть).

Так что я думал использовать 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 и секрет были созданы на 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. Но это говорит мне, что этот токен недействителен.

Я что-то упускаю или я делаю это не лучшим образом? Должен ли я сделать новую аутентификацию для API Google?

1 Ответ

0 голосов
/ 25 июня 2018

Существует ряд проблем с тем, как вы делаете то, что вы хотите сделать.

Во-первых, токен, который вы получаете в assertion, является Identity Token, а не авторизационным токеном.Токен сам по себе не является токеном на предъявителя, который разрешает вам делать что-либо от имени пользователя.Рекомендации, на которые вы указываете относительно потока утверждений, гласят, что вы должны проверить токен, а затем использовать его для получения уникального идентификатора пользователя из поля sub.Вы должны использовать этот идентификатор, чтобы определить, прошел ли пользователь проверку подлинности в вашей системе, и использовать токены аутентификации и обновления, которые у вас есть для пользователя.

Во-вторых, вам, вероятно, не нужен API Google+, так как Google + People object не содержит поля для номера телефона.Если это так, и если вы хотите использовать параметр "me" для получения личной информации о пользователе, вам потребуется запросить либо области авторизации https://www.googleapis.com/auth/plus.login, либо https://www.googleapis.com/auth/plus.me, когда пользователь входит в систему.

Вместо этого вы, вероятно, хотите использовать People API .Объект people содержит номера телефонов , которые можно получить с помощью метода get , но есть некоторые ограничения:

  • Онина самом деле должен быть установлен номер телефона, и вам нужно запросить это поле в качестве одного из полей для извлечения
  • Если они сделали его общедоступным, вы сможете его получить.
  • Еслиони не сделали его общедоступным, вам нужно запросить https://www.googleapis.com/auth/user.phonenumbers.read scope.
...