ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
エラー全文の典型例
GuzzleHttp\Exception\ClientException:
Client error: `POST https://accounts.google.com/o/oauth2/token` resulted in a
400 Bad Request response:
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
at vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113
from /vendor/laravel/socialite/src/Two/AbstractProvider.php:225
Laravel Socialite や PHP の google/apiclient、各種 OAuth ライブラリで Google にトークン交換要求を送ったとき、Google から 400 / 401 が返ってきた状態です。HTTP 400 + invalid_grant が最頻出。
エラー種別 (Google 公式)
| error | 意味 | 原因 |
|---|---|---|
invalid_grant | 付与コードが無効 | code 期限切れ / 既に使用済 / redirect_uri 不一致 / リフレッシュトークン失効 |
invalid_client | クライアント認証失敗 | client_id / client_secret 不一致 |
invalid_request | パラメータ不足・形式不正 | grant_type 漏れ / 必須パラメータ欠落 |
unauthorized_client | このクライアントは grant_type を使えない | クライアント種別ミス(Web/Native) |
invalid_scope | scope が無効 | 未公開 API / 承認画面で未掲載のスコープ |
access_denied | ユーザー拒否 | 同意画面で拒否を選択 |
原因 1: redirect_uri 不一致 — 最頻出
OAuth では、認可サーバーは「クライアント登録時の redirect_uri」と「トークン交換時に渡された redirect_uri」が完全一致するか確認します。1 文字でも違えば invalid_grant。
確認手順:
- Google Cloud Console → APIs & Services → 認証情報
- OAuth 2.0 クライアント ID を開く
- 承認済みのリダイレクト URI 欄を確認
- アプリ側の redirect_uri とスキーム・ホスト・ポート・パス・末尾スラッシュまで一致しているか確認
よくあるズレ:
| Console 登録 | アプリ送信 | 結果 |
|---|---|---|
http://localhost:8000/auth/google/callback | http://localhost:8000/auth/google/callback/ | NG(末尾 /) |
https://example.com/callback | http://example.com/callback | NG(http vs https) |
https://example.com/callback | https://www.example.com/callback | NG(www の有無) |
https://example.com:443/cb | https://example.com/cb | OK(デフォルトポートは省略可) |
原因 2: client_id / client_secret 不一致
環境変数の取り違え、改行混入、コピペ漏れが多い:
# .env をダンプして確認(先頭・末尾の空白に注意)
cat -A .env | grep GOOGLE
# Laravel での確認
php artisan tinker
>>> config('services.google')
=> [
"client_id" => "1234567890-abcdef.apps.googleusercontent.com",
"client_secret" => "GOCSPX-xxxxxxxxxxxxxxxxxxxx",
"redirect" => "http://localhost:8000/auth/google/callback",
]
# Console のクライアント ID と完全一致するか比較
原因 3: 認可コードの期限切れ・再利用
Google の認可コード(code=4/0Ad...)は発行から数分以内、かつ1 回しか使えません。よくある事故:
- デバッガで止めている間に期限切れ
- 同じ code で 2 回 token 交換した(リロード・テストで再実行)
- 非同期処理でレース条件
対処: フローを最初からやり直す(認可エンドポイントへリダイレクト)。
原因 4: scope 設定の不整合
承認画面 (OAuth Consent Screen) で公開していない scope を要求すると invalid_scope。または、scope を変えたのに同意画面の登録が古い:
- Cloud Console → 認証情報 → OAuth 同意画面
- スコープセクションに使う scope が登録されているか
- 機密スコープ(Gmail / Drive 等)は審査が必要
原因 5: Service Account との混同
サーバー間通信でユーザーログイン不要の場合は OAuth ではなく Service Account を使います。エンドポイントもフローも違う:
| 方式 | 用途 | credentials |
|---|---|---|
| OAuth 2.0 (Web Server) | ユーザーのデータにアクセス | client_id + client_secret + code |
| Service Account | サーバー単体での GCP リソース操作 | JSON 鍵ファイル (private_key で署名 JWT) |
| API Key | 公開 API(YouTube 検索等) | API キーのみ |
Laravel Socialite で出る典型ケース
// config/services.php
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT_URI'),
],
// .env
// GOOGLE_CLIENT_ID=1234-abcdef.apps.googleusercontent.com
// GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxx
// GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
// routes/web.php
Route::get('/auth/google', [GoogleAuth::class, 'redirect']);
Route::get('/auth/google/callback',[GoogleAuth::class, 'callback']);
// Controller
public function redirect()
{
return Socialite::driver('google')->redirect();
}
public function callback()
{
try {
$user = Socialite::driver('google')->user();
} catch (\Laravel\Socialite\Two\InvalidStateException $e) {
// セッション切れ → ログイン画面へ
return redirect('/login')->withErrors('セッションが切れました');
} catch (\GuzzleHttp\Exception\ClientException $e) {
// /token エラー
\Log::error($e->getResponse()->getBody()->getContents());
return redirect('/login')->withErrors('Google 連携に失敗しました');
}
}
リフレッシュトークン期限切れ
長期保持しているリフレッシュトークンが無効になると invalid_grant。原因:
- ユーザーが Google アカウント側でアクセス権を取り消した
- パスワード変更
- 6 か月以上未使用(テスト用アプリの場合は7 日で失効)
- Cloud Console で OAuth client を再生成した
対処: 再度 OAuth フローを実行してリフレッシュトークンを取り直す。access_type=offline と prompt=consent を必ず付ける:
return Socialite::driver('google')
->scopes(['openid', 'email', 'profile'])
->with(['access_type' => 'offline', 'prompt' => 'consent'])
->redirect();
デバッグの定石
- レスポンスボディを必ずログに出す(
error/error_description) - 送信パラメータを Wireshark / mitmproxy / Laravel HTTP ログで確認
- Cloud Console の監査ログを確認
- cURL で手動再現:
curl -X POST https://accounts.google.com/o/oauth2/token \
-d "code=4/0Ad..." \
-d "client_id=1234-abc.apps.googleusercontent.com" \
-d "client_secret=GOCSPX-..." \
-d "redirect_uri=http://localhost:8000/auth/google/callback" \
-d "grant_type=authorization_code"
FAQ
Q: ステージングと本番で同じクライアント ID を使ってよい?
A: 非推奨。redirect_uri を増やせば動くが、テスト中の不具合で本番ユーザーに影響しうる。環境ごとに別クライアント IDが推奨。
Q: テスト中に「verified ではないアプリ」と出る
A: OAuth 同意画面で「テストユーザー」に自分の Gmail を追加する。本番公開には Google 審査が必要(機密スコープ使用時)。
Q: ローカルでの redirect_uri は https にすべき?
A: localhost は http で許可される特殊扱い。それ以外は https 必須。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- Client error: POST https://accounts.google.com/o/oauth2/token
- Client error: GET https://www.googleapis.com/plus/v1/people/me?prettyPrint=false
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?