ハッカソン個人備忘録㉕：セキュリティに“ぬくもり”を。ポエム認証のプロトタイプを公開してみた

## はじめに

「ポジティブポエムを使った二段階認証」というユニークなアイデアを、Next.js（フロントエンド）で実装する方法を紹介します。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、まずフロントエンドの簡単なUIモックとローカルでの動かし方を中心に解説します。

---

## 認証フロー概要

### 1. 新規会員登録時
- ユーザ名、メールアドレス、パスワードを入力
- ポジティブポエムの一覧から1つを選択
- 上記情報をバックエンドに送信し、登録完了

### 2. ログイン時
- **ステップ1：** ユーザ名とパスワードを入力し、第一段階の認証を行う
- **ステップ2：** 登録時に選択したポエムをプルダウンから再選択し、ポエム認証（二段階目）を実施

---

## フロントエンド UI モック（事前準備）

以下は、React（Next.js）＋Tailwind CSS を使用した簡易UIのコード例です。

```jsx
import { useState } from "react";

export default function LoginPoemAuth() {
  const [step, setStep] = useState(1);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [selectedPoem, setSelectedPoem] = useState("");

  const poems = [
    "空を見上げて、今日も笑おう",
    "君の歩幅で、ゆっくり進もう",
    "風が背中を押してくれる",
  ];

  const handleLoginStep1 = async () => {
    // ここでAPIにusernameとpasswordを送信して認証
    // 成功したらstep2へ（本当はtokenもらう）
    setStep(2);
  };

  const handleLoginStep2 = async () => {
    // ここでAPIにpoemを送信して最終認証
    alert(`ポエム "${selectedPoem}" を選んでログインしました！`);
  };

  return (
    <div className="min-h-screen flex flex-col items-center justify-center p-4">
      {step === 1 && (
        <div className="w-full max-w-sm space-y-4">
          <h1 className="text-xl font-bold">ログイン - ステップ1</h1>
          <input
            type="text"
            placeholder="ユーザ名"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            className="w-full p-2 border rounded"
          />
          <input
            type="password"
            placeholder="パスワード"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            className="w-full p-2 border rounded"
          />
          <button onClick={handleLoginStep1} className="w-full bg-blue-500 text-white p-2 rounded">
            次へ
          </button>
        </div>
      )}

      {step === 2 && (
        <div className="w-full max-w-sm space-y-4">
          <h1 className="text-xl font-bold">ログイン - ステップ2（ポエム選択）</h1>
          <select
            value={selectedPoem}
            onChange={(e) => setSelectedPoem(e.target.value)}
            className="w-full p-2 border rounded"
          >
            <option value="">-- ポエムを選択 --</option>
            {poems.map((poem, idx) => (
              <option key={idx} value={poem}>{poem}</option>
            ))}
          </select>
          <button onClick={handleLoginStep2} className="w-full bg-green-500 text-white p-2 rounded">
            ログイン
          </button>
        </div>
      )}
    </div>
  );
}
```

---

## ローカルでの動作方法

### 1. 前提
- Node.js がインストールされている（推奨：v18）
- npm または yarn が使える

### 2. プロジェクト作成
```bash
npx create-next-app@latest poem-auth-app
cd poem-auth-app
```

プロンプトが出たら、以下のように回答すると**シンプルな構成**になります：

- **TypeScript** → No（今回は JS でOK）  
- **ESLint** → Yes（お好み）  
- **Tailwind CSS** → Yes ✅  
- **src ディレクトリ** → No  
- **App Router** → No（pagesディレクトリを使う）  
- **import alias** → No  

### 3. コードを追加
`pages/index.js` を上記の UI コードで置き換えます。

### 4. 開発サーバー起動
```bash
npm run dev
```
もしくは
```bash
yarn dev
```

ブラウザで `http://localhost:3000` にアクセスすれば、ステップ1 → ステップ2のポエム認証画面が動作します。

**実際のログイン画面**

![Screenshot 2025-04-10 at 20.03.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/f00470ac-a8ba-4a8e-b022-7d03b66fc6ae.png)

**実際のポエム認証画面**

![Screenshot 2025-04-10 at 20.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/234de3bc-ae41-4784-a334-83d0f942560f.png)

---

## おわりに

このプロトタイプをベースに、今後は以下のような拡張が可能です：
- FastAPI との API 連携（認証処理のバックエンド化）
- JWTトークンを使ったセッション管理
- 登録画面の追加
- ユーザー情報のDB保存

次回も引き続き開発を進めていくので、楽しみにしててください！