Google OAuth 設定ガイド
対象: Chat Story サービスへの Google ログイン実装
作成日: 2025年12月11日
概要
このドキュメントでは、Google Cloud Console で OAuth 2.0 認証情報(Client ID / Client Secret)を取得し、Better Auth と連携するまでの手順を解説します。
1. Google Cloud Console へのアクセス
Step 1: Google Cloud Console を開く
- 以下のURLにアクセス
https://console.cloud.google.com/ - Googleアカウントでログイン(まだの場合)
2. プロジェクトの作成
Step 2: 新規プロジェクト作成
- 画面上部の プロジェクト選択 ドロップダウンをクリック
- 「新しいプロジェクト」 をクリック
- プロジェクト情報を入力:
項目 入力例 プロジェクト名 chat-story場所 「組織なし」または所属組織 - 「作成」 をクリック
- 作成完了後、そのプロジェクトが選択されていることを確認
3. OAuth 同意画面の設定
Step 3: OAuth 同意画面を構成
※ この設定は必須です。先にこれをしないと認証情報を作成できません。
- 左側メニューから 「APIとサービス」 → 「OAuth 同意画面」 を選択
- User Type を選択:
タイプ 説明 推奨 外部 すべてのGoogleアカウントが対象 ◯ 一般公開サービス向け 内部 Google Workspace組織内のみ 社内ツール向け
→ 「外部」 を選択して 「作成」
- アプリ情報 を入力:
| 項目 | 入力内容 | 例 |
|---|---|---|
| アプリ名 | サービス名 | Chat Story |
| ユーザーサポートメール | 問い合わせ先 | support@example.com |
| アプリのロゴ | (任意)ロゴ画像 | - |
- アプリのドメイン(任意、本番環境用):
| 項目 | 入力内容 |
|---|---|
| アプリケーションのホームページ | https://chat-story.number55number55.workers.dev |
| プライバシーポリシーのリンク | https://chat-story.../privacy |
| 利用規約のリンク | https://chat-story.../terms |
- デベロッパーの連絡先情報:
- メールアドレスを入力
- 「保存して次へ」 をクリック
Step 4: スコープの設定
- 「スコープを追加または削除」 をクリック
- 以下のスコープを選択:
✅ .../auth/userinfo.email (メールアドレス取得) ✅ .../auth/userinfo.profile (プロフィール情報取得) ✅ openid (OpenID Connect) - 「更新」 をクリック
- 「保存して次へ」 をクリック
Step 5: テストユーザーの追加(開発中のみ)
※ 公開ステータスが「テスト」の間は、ここに登録したユーザーのみログイン可能です。
- 「+ ADD USERS」 をクリック
- テストに使用するGoogleアカウントのメールアドレスを追加
例: your-email@gmail.com - 「保存して次へ」 をクリック
- 概要を確認して 「ダッシュボードに戻る」
4. OAuth 認証情報の作成
Step 6: 認証情報を作成
- 左側メニューから 「APIとサービス」 → 「認証情報」 を選択
- 上部の 「+ 認証情報を作成」 をクリック
- 「OAuth クライアント ID」 を選択
- アプリケーションの種類 を選択:
ウェブ アプリケーション - 名前 を入力:
Chat Story Web Client - 承認済みの JavaScript 生成元(開発環境 + 本番環境):
http://localhost:3000 http://localhost:5173 https://chat-story.number55number55.workers.dev - 承認済みのリダイレクト URI(重要!):
http://localhost:3000/api/auth/callback/google http://localhost:5173/api/auth/callback/google https://chat-story.number55number55.workers.dev/api/auth/callback/google
⚠️ 注意: Better Auth のデフォルトコールバックパスは
/api/auth/callback/googleです。 カスタマイズしている場合は適宜変更してください。
- 「作成」 をクリック
Step 7: 認証情報を取得
作成完了すると、以下の情報が表示されます:
┌─────────────────────────────────────────────────────┐
│ OAuth クライアントを作成しました │
│ │
│ クライアント ID: │
│ 123456789-abcdefg.apps.googleusercontent.com │
│ │
│ クライアント シークレット: │
│ GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxx │
│ │
│ [JSON をダウンロード] [OK] │
└─────────────────────────────────────────────────────┘
この情報を安全な場所に保存してください!
- Client ID:
GOOGLE_CLIENT_IDとして使用 - Client Secret:
GOOGLE_CLIENT_SECRETとして使用
5. 環境変数の設定
Cloudflare Workers の場合
方法1: wrangler.toml に記載(開発用)
# wrangler.toml
[vars]
GOOGLE_CLIENT_ID = "123456789-abcdefg.apps.googleusercontent.com"
# シークレットは vars に書かない!
方法2: Wrangler CLI でシークレット設定(推奨)
# Client Secret を安全に設定
npx wrangler secret put GOOGLE_CLIENT_SECRET
# プロンプトが出たら値を入力
# 確認
npx wrangler secret list
方法3: Cloudflare Dashboard から設定
- https://dash.cloudflare.com/ にアクセス
- Workers & Pages → 対象のWorker を選択
- Settings → Variables タブ
- Environment Variables セクションで追加:
| Variable name | Value | Encrypt |
|---|---|---|
| GOOGLE_CLIENT_ID | 123456789-xxx.apps.googleusercontent.com | No |
| GOOGLE_CLIENT_SECRET | GOCSPX-xxx | Yes ✅ |
6. Better Auth での設定
auth.ts の設定
import { betterAuth } from "better-auth";
export const auth = betterAuth({
database: /* your database adapter */,
// メール/パスワード認証
emailAndPassword: {
enabled: true,
},
// Google OAuth
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
// オプション: 追加スコープ
// scope: ["email", "profile", "openid"],
},
},
});
Cloudflare Workers (Hono) での設定
// src/index.ts
import { Hono } from "hono";
import { auth } from "./auth";
type Bindings = {
GOOGLE_CLIENT_ID: string;
GOOGLE_CLIENT_SECRET: string;
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
// Better Auth のハンドラーを設定
app.on(["GET", "POST"], "/api/auth/*", (c) => {
return auth.handler(c.req.raw);
});
export default app;
// src/auth.ts (Cloudflare Workers 用)
import { betterAuth } from "better-auth";
import { D1Adapter } from "better-auth/adapters/d1";
export function createAuth(env: {
GOOGLE_CLIENT_ID: string;
GOOGLE_CLIENT_SECRET: string;
DB: D1Database;
}) {
return betterAuth({
database: D1Adapter(env.DB),
emailAndPassword: {
enabled: true,
},
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
},
},
});
}
7. クライアント側の実装
Google ログインボタン
// components/GoogleLoginButton.tsx
import { authClient } from "@/lib/auth-client";
export function GoogleLoginButton() {
const handleGoogleLogin = async () => {
await authClient.signIn.social({
provider: "google",
callbackURL: "/dashboard", // ログイン後のリダイレクト先
});
};
return (
<button
onClick={handleGoogleLogin}
className="flex items-center gap-2 px-4 py-2 border rounded-lg hover:bg-gray-50"
>
<GoogleIcon />
Googleでログイン
</button>
);
}
function GoogleIcon() {
return (
<svg className="w-5 h-5" viewBox="0 0 24 24">
<path
fill="#4285F4"
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
/>
<path
fill="#34A853"
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
/>
<path
fill="#FBBC05"
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
/>
<path
fill="#EA4335"
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
/>
</svg>
);
}
ログインページ全体の例
// pages/login.tsx
import { GoogleLoginButton } from "@/components/GoogleLoginButton";
import { authClient } from "@/lib/auth-client";
import { useState } from "react";
export function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const handleEmailLogin = async (e: React.FormEvent) => {
e.preventDefault();
try {
await authClient.signIn.email({ email, password });
window.location.href = "/dashboard";
} catch (err) {
setError("ログインに失敗しました");
}
};
return (
<div className="max-w-md mx-auto mt-20 p-6">
<h1 className="text-2xl font-bold mb-6">ログイン</h1>
{/* Google ログイン */}
<GoogleLoginButton />
<div className="my-6 flex items-center">
<hr className="flex-1" />
<span className="px-4 text-gray-500">または</span>
<hr className="flex-1" />
</div>
{/* メール/パスワード ログイン */}
<form onSubmit={handleEmailLogin} className="space-y-4">
{error && <p className="text-red-500">{error}</p>}
<input
type="email"
placeholder="メールアドレス"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full px-4 py-2 border rounded"
/>
<input
type="password"
placeholder="パスワード"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full px-4 py-2 border rounded"
/>
<button
type="submit"
className="w-full px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
ログイン
</button>
</form>
</div>
);
}
8. 本番公開時の設定
OAuth 同意画面を「本番」に変更
開発中は「テスト」モードですが、本番公開時は以下の手順が必要です:
- Google Cloud Console → OAuth 同意画面
- 「アプリを公開」 をクリック
- Google による審査(通常数日〜数週間)
- プライバシーポリシーページが必要
- 利用規約ページが必要
- ドメインの所有権確認が必要な場合あり
審査を避ける方法(小規模サービス向け)
以下の条件を満たす場合、審査なしで公開可能:
- 機密性の高いスコープを使用しない
email,profile,openidのみならOK- Gmail API や Drive API などは審査必要
- ユーザー数が100人未満
9. トラブルシューティング
エラー: "redirect_uri_mismatch"
原因: 設定したリダイレクトURIとアプリからのURIが一致しない
解決方法:
- Google Cloud Console で 承認済みのリダイレクト URI を確認
- 末尾のスラッシュ
/の有無を確認 httpとhttpsの違いを確認- ポート番号の確認
❌ http://localhost:3000/api/auth/callback/google/
✅ http://localhost:3000/api/auth/callback/google
エラー: "access_denied"
原因: テストモード中に未登録ユーザーがアクセス
解決方法:
- OAuth 同意画面 → テストユーザーに追加
- または「アプリを公開」で本番モードに
エラー: "invalid_client"
原因: Client ID または Client Secret が間違っている
解決方法:
- 環境変数が正しく設定されているか確認
- コピペ時の余分な空白がないか確認
- 認証情報を再作成
ログインしてもユーザー情報が取得できない
原因: スコープが不足している
解決方法:
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
scope: ["email", "profile", "openid"], // 明示的に指定
},
},
10. セキュリティ チェックリスト
✅ Client Secret は環境変数で管理(コードに直書きしない)
✅ Client Secret は暗号化して保存(Cloudflare の Encrypt オプション)
✅ 本番環境では HTTPS のみを許可
✅ 不要になった認証情報は削除
✅ 定期的に認証情報をローテーション
✅ OAuth 同意画面の情報を最新に保つ
参考リンク
| リソース | URL |
|---|---|
| Google Cloud Console | https://console.cloud.google.com/ |
| OAuth 2.0 ドキュメント | https://developers.google.com/identity/protocols/oauth2 |
| Better Auth - Google Provider | https://www.better-auth.com/docs/authentication/social-providers |
| Cloudflare Workers Secrets | https://developers.cloudflare.com/workers/configuration/secrets/ |
このドキュメントは Chat Story サービスの Google OAuth 設定ガイドとして作成されました。