0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的備忘録:Next.jsプロジェクトにPINコード認証付きログイン画面を作ってみた

Last updated at Posted at 2025-04-27

はじめに

Next.js (TypeScript) と Tailwind CSS を使って、ログイン画面を作成しました。

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

この画面は、一般ユーザーと管理者ユーザーで振る舞いを分け、管理者ユーザーにはPINコード入力による認証を設けています。

書こうと思ったきっかけ

簡単なデモアプリを作る中で、管理者用のアクセス制御を簡易的に実装してみたかったためです。セキュリティを意識した設計の第一歩として、PIN認証を試しました。

作成したコード

最初の宣言

"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
  • "use client" → Next.jsのApp Router環境で、「このコンポーネントはクライアント側で動くよ」と宣言
  • useState → Reactの状態管理フック
  • useRouter → ページ遷移に使用
  • Link → ページ間リンクを作る

useStateの設定とRouterの取得

const [showPinDialog, setShowPinDialog] = useState(false);
const [pinCode, setPinCode] = useState("");
const router = useRouter();
  • showPinDialog → PIN入力ダイアログの表示状態
  • pinCode → 入力されたPINを保持
  • router → ページをコード上で遷移する

管理者ボタンクリック時の処理

const handleAdminClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  e.preventDefault();
  setShowPinDialog(true);
};
  • リロードを防ぐ
  • PIN入力ダイアログを表示

PIN確認ボタン押下時の処理

const handleConfirmPin = () => {
  if (pinCode === "1234") {
    router.push("/admin-home");
  } else {
    alert("PINコードが間違っています!");
  }
};
  • PINが"1234"と一致すれば/admin-homeへ遷移
  • 違う場合はアラート出力

メイン画面のUI構成

<main className="flex flex-col items-center justify-center min-h-screen bg-[#0a0a0a] text-white p-8 pt-16 gap-10">
  • 黒背景、白文字、中央よせレイアウト

ログインタイトル

<h1 className="text-3xl font-bold bg-gray-200 text-black px-10 py-4 rounded">
  ログイン
</h1>
  • 大きめの文字で表示

入力フォーム

<input type="text" ... />
<input type="password" ... />
  • ユーザー名とパスワードの入力欄

ログイン種別ボタン

<button onClick={handleAdminClick}>管理ユーザー</button>
<Link href="/home">一般ユーザー</Link>
  • 管理ユーザーボタン:PIN入力ダイアログを開く
  • 一般ユーザーボタン:/homeへ遷移

戻るボタン

<Link href="/">戻る</Link>
  • トップページ(/)へ戻る

PIN入力ダイアログ

{showPinDialog && (
  <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
    ...
  </div>
)}
  • showPinDialogがtrueのときだけ表示
  • 半透明背景付きのダイアログ

ダイアログ内部

<input
  type="password"
  value={pinCode}
  onChange={(e) => setPinCode(e.target.value)}
  ...
/>
  • PIN入力を受け取り、pinCodeの値を更新
<button onClick={handleConfirmPin}>確認</button>
<button onClick={() => setShowPinDialog(false)}>キャンセル</button>
  • 確認ボタン:PINを検証
  • キャンセルボタン:ダイアログを閉じる

実際の画面

Screenshot 2025-04-28 at 6.13.48.png

Screenshot 2025-04-28 at 6.14.09.png

まとめ

今回の実装により、一般ユーザーと管理者ユーザーを区別したログイン画面をシンプルに作成できました。

管理者のみPIN認証を通過させる仕組みを取り入れることで、最小限ながらセキュリティを意識したフローを体験できました。

今後は、PINのハードコーディングをやめてサーバー連携するなど、さらに実用的なセキュリティ強化を目指していきたいです...!

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?