Ссылка на аккаунт и Google API

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

1

Решение

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

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

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

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

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

Другие решения

Других решений пока нет …