2.

Google+ API (plus/v1/people/me) 廃止エラーの対処: People API /

編集
この記事の要点
  • Google+ API は 2019 年 3 月にシャットダウンplus.googleapis.com 廃止
  • 古い OAuth ライブラリが https://www.googleapis.com/plus/v1/people/me を叩いて 404 / 410 を返す
  • 対処1: Google People API (people.googleapis.com/v1/people/me) に置き換え
  • 対処2: Google Sign-In の userinfo endpoint (oauth2/v3/userinfo) を使う
  • Laravel Socialite は 4.x → 5.x にアップグレードで自動修正済

エラーの正体

Laravel Socialite や古い OAuth クライアントが、Google ログイン後にユーザー情報を取得しようとして廃止された Google+ APIを呼んで失敗します:

GuzzleHttp\Exception\ClientException:
  Client error: `GET https://www.googleapis.com/plus/v1/people/me?prettyPrint=false`
  resulted in a `404 Not Found` response:
  {
    "error": {
      "code": 404,
      "message": "Method not found.",
      "status": "NOT_FOUND"
    }
  }

Google+ サービスは 2019 年 3 月 7 日に完全終了。これに伴い API (plus.googleapis.com, www.googleapis.com/plus/v1/...) も応答停止しました。古いライブラリは plus.profile.emails.read スコープと /plus/v1/people/me を叩く設計のままだとこのエラーが出ます。

対処1: Laravel Socialite を 5.x にアップグレード

Socialite 4.x は内部で Google+ API を呼んでいる。5.0 以降は People API ベースに刷新済:

# composer.json
composer require laravel/socialite:^5.0

# 古い場合
composer update laravel/socialite

# 確認
composer show laravel/socialite
# versions : * v5.x
// config/services.php
'google' => [
    'client_id'     => env('GOOGLE_CLIENT_ID'),
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    'redirect'      => env('GOOGLE_REDIRECT_URI'),
],

// routes/web.php
Route::get('/auth/google',          [AuthController::class, 'redirect']);
Route::get('/auth/google/callback', [AuthController::class, 'callback']);

// AuthController
public function redirect()
{
    return Socialite::driver('google')->redirect();
}

public function callback()
{
    $user = Socialite::driver('google')->user();

    // 5.x では People API 経由で取得
    $email  = $user->getEmail();
    $name   = $user->getName();
    $avatar = $user->getAvatar();
    $id     = $user->getId();

    // ログイン処理 ...
}

対処2: Google OpenID Connect の userinfo を使う

Socialite 以外のライブラリでも、OpenID Connect 標準の userinfo endpoint を使えば確実:

use GuzzleHttp\Client;

$http = new Client();
$res  = $http->get('https://openidconnect.googleapis.com/v1/userinfo', [
    'headers' => [
        'Authorization' => 'Bearer ' . $accessToken,
    ],
]);
$user = json_decode($res->getBody(), true);

/*
{
  "sub":            "1234567890",
  "name":           "山田 太郎",
  "given_name":     "太郎",
  "family_name":    "山田",
  "picture":        "https://lh3.googleusercontent.com/...",
  "email":          "taro@example.com",
  "email_verified": true,
  "locale":         "ja"
}
*/

// 必要なスコープ
// openid email profile

対処3: Google People API を使う

use GuzzleHttp\Client;

$http = new Client();
$res  = $http->get('https://people.googleapis.com/v1/people/me', [
    'headers' => [
        'Authorization' => 'Bearer ' . $accessToken,
    ],
    'query' => [
        'personFields' => 'names,emailAddresses,photos',
    ],
]);
$people = json_decode($res->getBody(), true);

/*
{
  "resourceName": "people/1234567890",
  "names": [{"displayName": "山田太郎", ...}],
  "emailAddresses": [{"value": "taro@example.com", "metadata": {...}}],
  "photos": [{"url": "https://...", ...}]
}
*/

// People API を使うには Google Cloud Console で
// "People API" を有効化する必要あり

スコープの修正

旧スコープ (廃止)新スコープ (有効)
https://www.googleapis.com/auth/plus.loginopenid
https://www.googleapis.com/auth/plus.meprofile
https://www.googleapis.com/auth/plus.profile.emails.reademail
https://www.googleapis.com/auth/userinfo.profileprofile (今も有効)
https://www.googleapis.com/auth/userinfo.emailemail (今も有効)

OAuth 同意画面の確認

  1. Google Cloud Console を開く: https://console.cloud.google.com/apis/credentials/consent
  2. OAuth 同意画面 → スコープ → plus.* 系を削除
  3. email / profile / openid のみ残す
  4. People API を使う場合は API ライブラリで「People API」を有効化
  5. クライアント側のスコープ指定も合わせて修正

Socialite カスタムスコープ指定

return Socialite::driver('google')
    ->scopes(['openid', 'profile', 'email'])
    ->with(['prompt' => 'select_account'])
    ->redirect();

// People API も合わせて呼ぶ場合
return Socialite::driver('google')
    ->scopes([
        'openid', 'profile', 'email',
        'https://www.googleapis.com/auth/contacts.readonly',
    ])
    ->redirect();

関連エラー

エラー原因対処
idpiframe_initialization_failedGoogle Sign-In JS の廃止 (2023/09)Google Identity Services (GIS) ライブラリへ移行
invalid_scope: plus.login廃止スコープ指定上表の新スコープに変更
Method not foundplus API 呼び出しPeople API or OIDC userinfo へ
403 PERMISSION_DENIEDPeople API 未有効化Cloud Console で有効化

FAQ

Q: 既存ユーザーの Google ID は引き継げる?
A: sub (subject) は id として継続使用可。plus.meid と OIDC の sub は同じ値です。

Q: Socialite を上げたくない
A: Socialite 4.x で動かすには内部の GoogleProvider を継承してエンドポイントを差し替えるパッチが必要。5.x へのアップグレードが圧倒的に楽

Q: Firebase Auth でも同様?
A: Firebase Auth は内部で OIDC を使うため影響なし。Firebase SDK の古いバージョンで plus.* を要求するパターンがあれば SDK 更新で解消。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Client error: POST https://accounts.google.com/o/oauth2/token
  2. Client error: GET https://www.googleapis.com/plus/v1/people/me?prettyPrint=false