1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-04-10

はじめに

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

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

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


認証フロー概要

1. 新規会員登録時

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

2. ログイン時

  • ステップ1: ユーザ名とパスワードを入力し、第一段階の認証を行う
  • ステップ2: 登録時に選択したポエムをプルダウンから再選択し、ポエム認証(二段階目)を実施

フロントエンド UI モック(事前準備)

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

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. プロジェクト作成

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. 開発サーバー起動

npm run dev

もしくは

yarn dev

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

実際のログイン画面

Screenshot 2025-04-10 at 20.03.53.png

実際のポエム認証画面

Screenshot 2025-04-10 at 20.04.46.png


おわりに

このプロトタイプをベースに、今後は以下のような拡張が可能です:

  • FastAPI との API 連携(認証処理のバックエンド化)
  • JWTトークンを使ったセッション管理
  • 登録画面の追加
  • ユーザー情報のDB保存

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

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?