Autenticacion de dos factores con Claude Code
Aprenda sobre autenticacion de dos factores usando Claude Code. Incluye ejemplos practicos de codigo.
二要素認証をClaude Codeで実装する
アカウントのセキュリティを強化する二要素認証(2FA)は、現在のWebアプリケーションに欠かせない機能です。Claude Codeを使えば、TOTPベースの2FA、QRコード表示、バックアップコードを含む完全な実装を構築できます。
TOTPの仕組み
TOTP(Time-based One-Time Password)は、共有シークレットと現在時刻から30秒ごとに6桁のコードを生成するアルゴリズムです。Google AuthenticatorやAuthyなどのアプリで利用されています。
> TOTPベースの二要素認証を実装して。
> QRコード生成、有効化フロー、ログイン時の検証、
> バックアップコード10個の生成も含めて。
シークレット生成とQRコード
// src/lib/two-factor.ts
import { authenticator } from 'otplib';
import QRCode from 'qrcode';
import crypto from 'crypto';
import { prisma } from './prisma';
export class TwoFactorService {
// 2FA設定の開始(シークレットとQRコード生成)
async setup(userId: string) {
const secret = authenticator.generateSecret();
const user = await prisma.user.findUnique({ where: { id: userId } });
const otpauthUrl = authenticator.keyuri(
user!.email,
'MyApp',
secret
);
const qrCodeDataUrl = await QRCode.toDataURL(otpauthUrl);
// シークレットを一時保存(まだ有効化しない)
await prisma.user.update({
where: { id: userId },
data: { twoFactorSecret: secret, twoFactorEnabled: false },
});
return { qrCodeDataUrl, secret };
}
// コードを検証して2FAを有効化
async enable(userId: string, token: string) {
const user = await prisma.user.findUnique({ where: { id: userId } });
if (!user?.twoFactorSecret) throw new Error('2FAが設定されていません');
const isValid = authenticator.verify({
token,
secret: user.twoFactorSecret,
});
if (!isValid) throw new Error('無効なコードです');
// バックアップコードを生成
const backupCodes = this.generateBackupCodes();
const hashedCodes = backupCodes.map((code) =>
crypto.createHash('sha256').update(code).digest('hex')
);
await prisma.user.update({
where: { id: userId },
data: {
twoFactorEnabled: true,
backupCodes: hashedCodes,
},
});
return { backupCodes }; // ユーザーに表示(一度だけ)
}
// ログイン時のコード検証
async verify(userId: string, token: string): Promise<boolean> {
const user = await prisma.user.findUnique({ where: { id: userId } });
if (!user?.twoFactorSecret) return false;
// TOTPコードで検証
const isValid = authenticator.verify({
token,
secret: user.twoFactorSecret,
});
if (isValid) return true;
// バックアップコードで検証
const hashedToken = crypto.createHash('sha256').update(token).digest('hex');
const codeIndex = user.backupCodes.indexOf(hashedToken);
if (codeIndex !== -1) {
// 使用済みのバックアップコードをDelete
const updatedCodes = [...user.backupCodes];
updatedCodes.splice(codeIndex, 1);
await prisma.user.update({
where: { id: userId },
data: { backupCodes: updatedCodes },
});
return true;
}
return false;
}
private generateBackupCodes(count = 10): string[] {
return Array.from({ length: count }, () =>
crypto.randomBytes(4).toString('hex').toUpperCase()
);
}
}
2FA設定画面
// src/components/TwoFactorSetup.tsx
'use client';
import { useState } from 'react';
export function TwoFactorSetup() {
const [step, setStep] = useState<'idle' | 'qr' | 'verify' | 'backup'>('idle');
const [qrCode, setQrCode] = useState('');
const [token, setToken] = useState('');
const [backupCodes, setBackupCodes] = useState<string[]>([]);
const startSetup = async () => {
const res = await fetch('/api/user/2fa/setup', { method: 'POST' });
const data = await res.json();
setQrCode(data.qrCodeDataUrl);
setStep('qr');
};
const verifyAndEnable = async () => {
const res = await fetch('/api/user/2fa/enable', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token }),
});
const data = await res.json();
setBackupCodes(data.backupCodes);
setStep('backup');
};
if (step === 'idle') {
return (
<button onClick={startSetup} className="bg-blue-600 text-white px-6 py-2 rounded-lg">
二要素認証を設定する
</button>
);
}
if (step === 'qr') {
return (
<div className="space-y-4">
<p className="dark:text-gray-300">認証アプリでQRコードをスキャンしてください</p>
<img src={qrCode} alt="QRコード" className="mx-auto" />
<input
value={token}
onChange={(e) => setToken(e.target.value)}
placeholder="6桁のコードを入力"
className="w-full border rounded px-3 py-2"
maxLength={6}
/>
<button onClick={verifyAndEnable} className="bg-blue-600 text-white px-6 py-2 rounded-lg w-full">
確認して有効化
</button>
</div>
);
}
return (
<div className="space-y-4">
<h3 className="font-bold text-green-600">二要素認証が有効になりました</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">
以下のバックアップコードを安全な場所に保存してください。各コードは一度だけ使えます。
</p>
<div className="grid grid-cols-2 gap-2 bg-gray-50 dark:bg-gray-800 p-4 rounded-lg font-mono text-sm">
{backupCodes.map((code, i) => (
<span key={i} className="dark:text-gray-300">{code}</span>
))}
</div>
</div>
);
}
関連記事
認証全般については認証機能の実装ガイド、パスワード関連はパスワードリセット実装も参考にしてください。
TOTPの仕様はRFC 6238で定義されています。
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
7 comprobaciones antes de publicar cada día un artículo multilingüe sobre Claude Code
Una lista práctica para publicar artículos multilingües sobre Claude Code todos los días sin olvidar idiomas, romper CTAs ni dejar páginas antiguas en producción.
Que es Codex Automations y como dejar que la IA gestione contenido mientras duermes
Guia practica para usar Codex Automations en analitica, articulos, CTA, despliegue y monetizacion.
Claude Code × GCP Cloud Functions Guía Completa | Desarrollo Serverless Ultrarrápido
Optimiza GCP Cloud Functions con Claude Code. Implementa triggers HTTP/Pub/Sub/Firestore, pruebas locales y automatización de despliegues con ejemplos de código reales de la experiencia de Masa.