Connexion sociale avec Claude Code
Découvrez connexion sociale avec Claude Code. Conseils pratiques et exemples de code inclus.
ソーシャルログインをClaude Codeで実装する
ソーシャルログインを導入すると、ユーザーの登録ハードルが大幅に下がります。Google、GitHub、X(旧Twitter)など複数のプロバイダーに対応するのは設定が複雑ですが、Claude Codeを使えば一貫した実装で効率的に構築できます。
NextAuth.jsによるマルチプロバイダー設定
> NextAuth.jsでソーシャルログインを実装して。
> Google、GitHub、Xの3つのプロバイダーに対応して。
> 既存アカウントとのリンク機能も含めて。
// src/lib/auth.ts
import NextAuth from 'next-auth';
import Google from 'next-auth/providers/google';
import GitHub from 'next-auth/providers/github';
import Twitter from 'next-auth/providers/twitter';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from './prisma';
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
authorization: {
params: {
prompt: 'consent',
access_type: 'offline',
response_type: 'code',
},
},
}),
GitHub({
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
}),
Twitter({
clientId: process.env.TWITTER_CLIENT_ID!,
clientSecret: process.env.TWITTER_CLIENT_SECRET!,
version: '2.0',
}),
],
callbacks: {
async signIn({ user, account, profile }) {
// 既存ユーザーの場合はアカウントをリンク
if (account && user.email) {
const existingUser = await prisma.user.findUnique({
where: { email: user.email },
});
if (existingUser) {
await prisma.account.upsert({
where: {
provider_providerAccountId: {
provider: account.provider,
providerAccountId: account.providerAccountId,
},
},
update: {},
create: {
userId: existingUser.id,
provider: account.provider,
providerAccountId: account.providerAccountId,
type: account.type,
access_token: account.access_token,
refresh_token: account.refresh_token,
},
});
}
}
return true;
},
async session({ session, user }) {
session.user.id = user.id;
return session;
},
},
pages: {
signIn: '/login',
error: '/login?error=auth',
},
});
ログインページのUI
// src/app/(auth)/login/page.tsx
'use client';
import { signIn } from 'next-auth/react';
const providers = [
{ id: 'google', name: 'Google', icon: '🔍', bg: 'bg-white border hover:bg-gray-50', text: 'text-gray-700' },
{ id: 'github', name: 'GitHub', icon: '🐙', bg: 'bg-gray-900 hover:bg-gray-800', text: 'text-white' },
{ id: 'twitter', name: 'X (Twitter)', icon: '𝕏', bg: 'bg-black hover:bg-gray-900', text: 'text-white' },
];
export default function LoginPage() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
<div className="bg-white dark:bg-gray-800 p-8 rounded-2xl shadow-lg w-full max-w-md">
<h1 className="text-2xl font-bold text-center mb-2 dark:text-white">ログイン</h1>
<p className="text-gray-500 text-center mb-8">アカウントでログインしてください</p>
<div className="space-y-3">
{providers.map((provider) => (
<button
key={provider.id}
onClick={() => signIn(provider.id, { callbackUrl: '/dashboard' })}
className={`w-full flex items-center justify-center gap-3 px-4 py-3 rounded-lg font-medium transition ${provider.bg} ${provider.text}`}
>
<span className="text-xl">{provider.icon}</span>
{provider.name}でログイン
</button>
))}
</div>
<div className="mt-6 text-center text-sm text-gray-500">
ログインすることで
<a href="/terms" className="text-blue-600 hover:underline">利用規約</a>と
<a href="/privacy" className="text-blue-600 hover:underline">プライバシーポリシー</a>に同意します
</div>
</div>
</div>
);
}
アカウントリンク管理
// src/components/LinkedAccounts.tsx
'use client';
import { useState, useEffect } from 'react';
interface LinkedAccount {
provider: string;
providerAccountId: string;
linkedAt: string;
}
export function LinkedAccounts() {
const [accounts, setAccounts] = useState<LinkedAccount[]>([]);
useEffect(() => {
fetch('/api/user/linked-accounts')
.then((res) => res.json())
.then(setAccounts);
}, []);
const unlinkAccount = async (provider: string) => {
if (accounts.length <= 1) {
alert('最低1つのログイン方法が必要です');
return;
}
await fetch(`/api/user/linked-accounts/${provider}`, { method: 'DELETE' });
setAccounts(accounts.filter((a) => a.provider !== provider));
};
return (
<div className="space-y-4">
<h3 className="font-semibold dark:text-white">連携済みアカウント</h3>
{accounts.map((account) => (
<div key={account.provider} className="flex items-center justify-between p-3 border rounded-lg dark:border-gray-700">
<span className="capitalize dark:text-gray-300">{account.provider}</span>
<button
onClick={() => unlinkAccount(account.provider)}
className="text-red-500 text-sm hover:underline"
>
解除
</button>
</div>
))}
</div>
);
}
セキュリティのポイント
ソーシャルログインではCSRF対策とstateパラメータの検証が重要です。NextAuth.jsはこれらをデフォルトで処理しますが、カスタム実装する場合はClaude Codeに「OAuthのセキュリティベストプラクティスに沿って実装して」と指示しましょう。
関連記事
OAuth全般の実装パターンはOAuth実装ガイド、JWT認証と組み合わせる場合はJWT認証の実装も参考になります。
NextAuth.jsの公式ドキュメント(next-auth.js.org)でプロバイダーごとの詳細設定を確認できます。
PDF gratuit : aide-mémoire Claude Code en 5 minutes
Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.
Nous traitons vos données avec soin et n'envoyons jamais de spam.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
7 vérifications avant de publier chaque jour un article multilingue sur Claude Code
Une checklist pratique pour publier des articles multilingues sur Claude Code chaque jour sans oublier une langue, casser les CTA ou laisser l’ancien contenu en production.
Codex Automations : confier l'analyse, les articles et le deploiement a l'IA
Guide pratique pour utiliser Codex Automations dans une operation de contenu orientee monetisation.
Claude Code × GCP Cloud Functions Guide Complet | Développement Serverless Ultra-Rapide
Optimisez GCP Cloud Functions avec Claude Code. Implémentez des triggers HTTP/Pub/Sub/Firestore, des tests locaux et l'automatisation des déploiements avec des exemples de code réels de l'expérience de Masa.