0%
実装パターン#ソーシャルログイン#OAuth#認証

ソーシャルログインの実装|Google/GitHub/Xログインの作り方

各種ソーシャルログインの実装方法。Google、GitHub、X(Twitter)、Appleログインを解説。

||11分で読める

ソーシャルログインの実装

パスワード不要で登録率UP。

ソーシャルログインのメリット

ユーザー側:
- パスワードを覚えなくていい
- 登録が1クリック
- 信頼性がある

開発者側:
- パスワード管理不要
- メール確認不要
- プロフィール情報が取れる

Supabaseで実装

Googleログイン

1. Google Cloud Consoleで認証情報作成
2. SupabaseでGoogle Providerを有効化
3. Client ID/Secretを設定
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(url, key)

async function signInWithGoogle() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'google',
    options: {
      redirectTo: `${window.location.origin}/auth/callback`,
    },
  })
}

GitHubログイン

1. GitHub Developer SettingsでOAuth App作成
2. SupabaseでGitHub Providerを有効化
3. Client ID/Secretを設定
async function signInWithGitHub() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'github',
  })
}

Xログイン

1. Twitter Developer PortalでApp作成
2. OAuth 2.0を有効化
3. SupabaseでTwitter Providerを有効化
async function signInWithTwitter() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'twitter',
  })
}

Auth.jsで実装

インストール

npm install next-auth

設定

// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import Google from 'next-auth/providers/google'
import GitHub from 'next-auth/providers/github'

const handler = NextAuth({
  providers: [
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    GitHub({
      clientId: process.env.GITHUB_ID!,
      clientSecret: process.env.GITHUB_SECRET!,
    }),
  ],
})

export { handler as GET, handler as POST }

クライアントで使用

'use client'

import { signIn, signOut, useSession } from 'next-auth/react'

export function AuthButton() {
  const { data: session } = useSession()

  if (session) {
    return (
      <div>
        <p>{session.user?.name}</p>
        <button onClick={() => signOut()}>ログアウト</button>
      </div>
    )
  }

  return (
    <div>
      <button onClick={() => signIn('google')}>Googleでログイン</button>
      <button onClick={() => signIn('github')}>GitHubでログイン</button>
    </div>
  )
}

プロバイダー設定

Google

1. console.cloud.google.com
2. 新しいプロジェクト作成
3. OAuth同意画面を設定
4. 認証情報 → OAuthクライアントID作成
5. リダイレクトURIを設定

GitHub

1. github.com/settings/developers
2. New OAuth App
3. Authorization callback URL設定
4. Client ID/Secretをコピー

Apple

1. developer.apple.com
2. Identifiers → App IDs
3. Sign In with Appleを有効化
4. Keys → Sign In with Apple用キー作成

UIの例

function LoginButtons() {
  return (
    <div className="space-y-3">
      <button
        onClick={() => signIn('google')}
        className="w-full flex items-center justify-center gap-2 px-4 py-2 border rounded-lg hover:bg-gray-50"
      >
        <GoogleIcon />
        Googleで続ける
      </button>

      <button
        onClick={() => signIn('github')}
        className="w-full flex items-center justify-center gap-2 px-4 py-2 bg-gray-900 text-white rounded-lg hover:bg-gray-800"
      >
        <GitHubIcon />
        GitHubで続ける
      </button>

      <div className="relative">
        <div className="absolute inset-0 flex items-center">
          <div className="w-full border-t" />
        </div>
        <div className="relative flex justify-center text-sm">
          <span className="bg-white px-2 text-gray-500">または</span>
        </div>
      </div>

      <button className="w-full px-4 py-2 border rounded-lg">
        メールで続ける
      </button>
    </div>
  )
}

注意点

スコープ設定

// 必要な権限のみ要求
signInWithOAuth({
  provider: 'google',
  options: {
    scopes: 'email profile',  // 最小限
  },
})

プロフィール同期

// 初回ログイン時にユーザー作成
const { data: { user } } = await supabase.auth.getUser()

if (user) {
  await prisma.user.upsert({
    where: { id: user.id },
    update: { name: user.user_metadata.full_name },
    create: {
      id: user.id,
      email: user.email!,
      name: user.user_metadata.full_name,
    },
  })
}

次のステップ

シェア:

参考文献・引用元

実装パターンの他の記事

他のカテゴリも見る