Use Cases

Mengimplementasikan Two-Factor Authentication (2FA) dengan Claude Code

Learn about implementing two-factor authentication (2fa) using Claude Code. Includes practical code examples.

二elemen認証 dengan Claude Code: implementasi

アカウント セキュリティ 強化 二elemen認証(2FA) 、現在 Webaplikasi 欠かせ tidak機能.Claude Code 使えば、TOTPベース 2FA、QRコードtampilan、バックアップコード 含む完全なimplementasi pembangunan bisa dilakukan.

mekanisme TOTP

TOTP(Time-based One-Time Password) 、berbagiシークレット dan 現在時刻 dari 30秒ご dan 6桁 コード generate algoritma.Google AuthenticatorやAuthy dll. aplikasi pemanfaatanされてい.

> TOTPベース 二elemen認証 implementasikan.
> QRコードgenerate、efektif化フロー、login時 verifikasi、
> バックアップコード10個 generate juga 含めて。

シークレットgenerateと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 {
  // 2FApengaturan mulai(シークレット dan QRコードgenerate)
  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);

    // シークレット 一時penyimpanan(まだefektif化し tidak)
    await prisma.user.update({
      where: { id: userId },
      data: { twoFactorSecret: secret, twoFactorEnabled: false },
    });

    return { qrCodeDataUrl, secret };
  }

  // コード verifikasi 2FA efektif化
  async enable(userId: string, token: string) {
    const user = await prisma.user.findUnique({ where: { id: userId } });
    if (!user?.twoFactorSecret) throw new Error('2FA pengaturanされていません');

    const isValid = authenticator.verify({
      token,
      secret: user.twoFactorSecret,
    });

    if (!isValid) throw new Error('無効なコード す');

    // バックアップコード generate
    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 }; // pengguna tampilan(一度だけ)
  }

  // login時 コードverifikasi
  async verify(userId: string, token: string): Promise<boolean> {
    const user = await prisma.user.findUnique({ where: { id: userId } });
    if (!user?.twoFactorSecret) return false;

    // TOTPコード verifikasi
    const isValid = authenticator.verify({
      token,
      secret: user.twoFactorSecret,
    });

    if (isValid) return true;

    // バックアップコード verifikasi
    const hashedToken = crypto.createHash('sha256').update(token).digest('hex');
    const codeIndex = user.backupCodes.indexOf(hashedToken);
    if (codeIndex !== -1) {
      // penggunaan済み バックアップコード 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()
    );
  }
}

2FApengaturan画面

// 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桁 コード input"
          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>
  );
}

Artikel Terkait

認証全般 mengenai 認証機能 implementasipanduan、パスワード関連 パスワードリセットimplementasi juga bisa dijadikan referensi.

TOTP 仕様 RFC 6238 definisiされてい.

#Claude Code #two-factor auth #2FA #TOTP #security
Gratis

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Cukup masukkan emailmu dan kami akan langsung mengirim cheatsheet PDF A4 satu halaman.

Kami menjaga data pribadimu dengan aman dan tidak pernah mengirim spam.

Masa

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.