ホームページ  >  記事  >  ウェブフロントエンド  >  顔認証を使用した安全な従業員ダッシュボードの構築: 包括的な Next.js チュートリアル

顔認証を使用した安全な従業員ダッシュボードの構築: 包括的な Next.js チュートリアル

WBOY
WBOYオリジナル
2024-07-18 18:16:41646ブラウズ

職場の管理に革命を起こす準備はできていますか?この包括的なチュートリアルでは、顔認証を活用した最先端の従業員ダッシュボードの作成について詳しく説明します。 Web 開発で最も人気のあるツールのいくつかである Next.js、FACEIO、Shadcn UI を使用します。このガイドを終える頃には、従業員が未来に生きていると感じられる、洗練された安全なダッシュボードが完成します!

始める前に必要なもの

本題に入る前に、すべてのアヒルが揃っていることを確認しましょう:

  • マシンにインストールされている Node.js
  • npm または Yarn (ボートを浮かべるもの)

もうわかりましたか?素晴らしい!この番組を放送しましょう。

Faceio Authentication

プロジェクトのセットアップ: 最初のステップ

ステップ 1: Next.js プロジェクトを開始する

まず最初に、Next.js プロジェクトを作成しましょう。ターミナルを開いて、次の魔法の言葉を入力してください:

npx create-next-app@latest faceio-app
cd faceio-app

いくつか質問されます。答え方は次のとおりです:

  • TypeScript?そうそう!
  • ESLint?絶対に!
  • Tailwind CSS?
  • src/ ディレクトリ?いや、大丈夫です。
  • アプリルーター?はい、お願いします!
  • デフォルトのインポートエイリアスをカスタマイズしますか?これは譲ります。

ステップ 2: ツールを集める

さて、必要なグッズをすべて手に入れましょう。次のコマンドを実行して依存関係をインストールします:

npm install @faceio/fiojs @shadcn/ui class-variance-authority clsx tailwind-merge

ステップ 3: 秘密のソースを設定する

プロジェクトのルートに .env.local というファイルを作成します。ここに秘密の FACEIO アプリ ID を保管します:

NEXT_PUBLIC_FACEIO_APP_ID=your-super-secret-faceio-app-id

「your-super-secret-faceio-app-id」を実際の FACEIO アプリケーション ID に忘れずに置き換えてください。安全に保管してください!

ステップ 4: ファイル構造

プロジェクトの構造は次のようになります:

faceio-app/
├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   └── components/
│       ├── FaceAuth.tsx
│       └── EmployeeDashboard.tsx
├── public/
├── .env.local
├── next.config.js
├── package.json
├── tsconfig.json
└── tailwind.config.js

ステップ 5: Tailwind CSS を整える

Tailwind を変身させる時が来ました。この派手な構成で tailwind.config.js ファイルを更新します:

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ["class"],
  content: [
    './app/**/*.{ts,tsx}',
  ],
  theme: {
    container: {
      center: true,
      padding: "2rem",
      screens: {
        "2xl": "1400px",
      },
    },
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
      keyframes: {
        "accordion-down": {
          from: { height: 0 },
          to: { height: "var(--radix-accordion-content-height)" },
        },
        "accordion-up": {
          from: { height: "var(--radix-accordion-content-height)" },
          to: { height: 0 },
        },
      },
      animation: {
        "accordion-down": "accordion-down 0.2s ease-out",
        "accordion-up": "accordion-up 0.2s ease-out",
      },
    },
  },
  plugins: [require("tailwindcss-animate")],
}

ダッシュボードの中心部を構築する

ステップ 1: FaceAuth コンポーネントの作成

番組の主役である FaceAuth コンポーネントを作成しましょう。新しいファイル app/components/FaceAuth.tsx を作成し、次のコードを貼り付けます:

import { useEffect } from 'react';
import faceIO from '@faceio/fiojs';
import { Button, Card, CardHeader, CardTitle, CardContent } from '@shadcn/ui';
import { useToast } from '@shadcn/ui';

interface FaceAuthProps {
  onSuccessfulAuth: (data: any) => void;
}

const FaceAuth: React.FC<FaceAuthProps> = ({ onSuccessfulAuth }) => {
  const { toast } = useToast();

  useEffect(() => {
    const faceio = new faceIO(process.env.NEXT_PUBLIC_FACEIO_APP_ID);

    const enrollNewUser = async () => {
      try {
        const userInfo = await faceio.enroll({
          locale: 'auto',
          payload: {
            email: 'employee@example.com',
            pin: '12345',
          },
        });
        toast({
          title: "Success!",
          description: "You're now enrolled in the facial recognition system!",
        });
        console.log('User Enrolled!', userInfo);
      } catch (errCode) {
        toast({
          title: "Oops!",
          description: "Enrollment failed. Please try again.",
          variant: "destructive",
        });
        console.error('Enrollment Failed', errCode);
      }
    };

    const authenticateUser = async () => {
      try {
        const userData = await faceio.authenticate();
        toast({
          title: "Welcome back!",
          description: "Authentication successful.",
        });
        console.log('User Authenticated!', userData);
        onSuccessfulAuth({
          name: 'John Doe',
          position: 'Software Developer',
          department: 'Engineering',
          photoUrl: 'https://example.com/john-doe.jpg',
        });
      } catch (errCode) {
        toast({
          title: "Authentication failed",
          description: "Please try again or enroll.",
          variant: "destructive",
        });
        console.error('Authentication Failed', errCode);
      }
    };

    const enrollBtn = document.getElementById('enroll-btn');
    const authBtn = document.getElementById('auth-btn');

    if (enrollBtn) enrollBtn.onclick = enrollNewUser;
    if (authBtn) authBtn.onclick = authenticateUser;

    return () => {
      if (enrollBtn) enrollBtn.onclick = null;
      if (authBtn) authBtn.onclick = null;
    };
  }, [toast, onSuccessfulAuth]);

  return (
    <Card className="w-full max-w-md mx-auto">
      <CardHeader>
        <CardTitle>Facial Authentication</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <Button id="enroll-btn" variant="outline" className="w-full">
          Enroll New Employee
        </Button>
        <Button id="auth-btn" variant="default" className="w-full">
          Authenticate
        </Button>
      </CardContent>
    </Card>
  );
};

export default FaceAuth;

ステップ 2: EmployeeDashboard コンポーネントの構築

次に、従業員が見るダッシュボードを作成しましょう。 app/components/EmployeeDashboard.tsx を作成します:

import { useState } from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@shadcn/ui';
import { Button, Avatar, Badge, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shadcn/ui';
import FaceAuth from './FaceAuth';

interface EmployeeData {
  name: string;
  position: string;
  department: string;
  photoUrl: string;
}

const EmployeeDashboard: React.FC = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [employeeData, setEmployeeData] = useState<EmployeeData | null>(null);

  const handleSuccessfulAuth = (data: EmployeeData) => {
    setIsAuthenticated(true);
    setEmployeeData(data);
  };

  const mockAttendanceData = [
    { date: '2024-07-14', timeIn: '09:00 AM', timeOut: '05:30 PM' },
    { date: '2024-07-13', timeIn: '08:55 AM', timeOut: '05:25 PM' },
    { date: '2024-07-12', timeIn: '09:05 AM', timeOut: '05:35 PM' },
  ];

  return (
    <div className="space-y-6">
      {!isAuthenticated ? (
        <FaceAuth onSuccessfulAuth={handleSuccessfulAuth} />
      ) : (
        <>
          <Card>
            <CardHeader>
              <CardTitle>Employee Profile</CardTitle>
            </CardHeader>
            <CardContent className="flex items-center space-x-4">
              <Avatar className="h-20 w-20" src={employeeData?.photoUrl} alt={employeeData?.name} />
              <div>
                <h2 className="text-2xl font-bold">{employeeData?.name}</h2>
                <p className="text-gray-500">{employeeData?.position}</p>
                <Badge variant="outline">{employeeData?.department}</Badge>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Quick Actions</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <Button className="w-full">Check-in</Button>
              <Button className="w-full" variant="secondary">Request Leave</Button>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Attendance Records</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Date</TableHead>
                    <TableHead>Time In</TableHead>
                    <TableHead>Time Out</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {mockAttendanceData.map((record, index) => (
                    <TableRow key={index}>
                      <TableCell>{record.date}</TableCell>
                      <TableCell>{record.timeIn}</TableCell>
                      <TableCell>{record.timeOut}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </>
      )}
    </div>
  );
};

export default EmployeeDashboard;

ステップ 3: すべてをまとめる

最後に、メイン ページを更新して、私たちの頑張りを披露しましょう。 app/page.tsx を更新します:

import EmployeeDashboard from './components/EmployeeDashboard';

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-4">
      <EmployeeDashboard />
    </main>
  );
}

次に、アプリ全体をラップするレイアウトを設定しましょう。次のコードを追加します: app/layout.tsx

import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Employee Dashboard with Facial Authentication',
  description: 'A cutting-edge employee dashboard featuring facial recognition for secure authentication and efficient workplace management.',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <header className="bg-primary text-white p-4">
          <h1 className="text-2xl font-bold">Faceio Solutions</h1>
        </header>
        <main className="container mx-auto p-4">
          {children}
        </main>
        <footer className="bg-gray-100 text-center p-4 mt-8">
          <p>&copy; 2024 Faceio . All rights reserved.</p>
        </footer>
      </body>
    </html>
  )
}

このレイアウトは家のフレームのようなもので、アプリ全体の構造を提供します。これには、会社名が記載されたヘッダー、ダッシュボードが表示されるメイン コンテンツ領域、およびフッターが含まれます。さらに、メタデータを使用した SEO の魔法もセットアップされます!

FACEIO 統合のための重要なプライバシーとセキュリティの実践

プライバシーバイデザイン

  • アクセス制御、ユーザーの同意、オプトアウトのオプションを使用してプライバシーを保護します。

意味のある同意

  • ユーザーがデータ収集について認識していることを確認します。
  • データに対する選択と制御の自由を提供します。
  • いつでも同意の取り消しとデータの削除を許可します。

ベストプラクティス

  • 特に未成年者の場合は、明確かつ適切な同意を取得してください。
  • 同意リクエストを簡単に見つけて理解できるようにします。
  • 自動登録や不正な登録は避けてください。
  • 生体認証データを収集する前にユーザーに通知します。
  • 法的なデータプライバシー要件に従ってください。

データセキュリティ

  • アカウント削除時にユーザーデータを削除します。
  • データの強力な保存と廃棄の慣行を維持します。
  • セキュリティ保護措置を定期的に実装し、確認します。

詳細については、FACEIO のベスト プラクティスを参照してください。

FACEIO 統合に関する重要なセキュリティ上の考慮事項

設計によるセキュリティ

  • ユーザーの信頼を維持するには、アプリケーションのセキュリティが不可欠です。
  • リスクを軽減するには、FACEIO のセキュリティのベスト プラクティスに従ってください。

コアセキュリティ機能

  1. 弱い PIN を拒否する

    • 0000 や 1234 などの弱い PIN を防止します。
    • デフォルト: いいえ
  2. 重複登録を防止します

    • ユーザーが複数回登録できないようにします。
    • デフォルト: いいえ
  3. ディープフェイクから保護

    • なりすましの試みを検出してブロックします。
    • デフォルト: いいえ
  4. 未成年者の登録を禁止します

    • 18 歳未満のユーザーの登録をブロックします。
    • デフォルト: いいえ
  5. 認証には PIN が必要です

    • 各認証には PIN コードが必要です。
    • デフォルト: はい。
  6. 一意の PIN を強制する

    • 各ユーザーの PIN が一意であることを確認します。
    • デフォルト: いいえ
  7. 隠れた顔を無視する

    • 照明が不十分な場合、または部分的にマスクされている場合は顔を破棄します。
    • デフォルト: はい。
  8. 欠落したヘッダーを拒否

    • 適切な HTTP ヘッダーのないインスタンス化をブロックします。
    • デフォルト: はい。
  9. インスタンス化を制限する

    • 特定のドメインと国に制限されます。
    • デフォルト: いいえ
  10. Webhook を有効にする

    • FACEIO イベントをバックエンドに通知します。
    • デフォルト: いいえ

詳細については、FACEIO セキュリティのベスト プラクティスを参照してください。

現実世界のアプリケーション: これはどこで使用できますか?

この素晴らしいダッシュボードを構築したので、「これを現実世界のどこで使用できるの?」と疑問に思っているかもしれません。そうですね、言っておきますが、可能性は無限大です!ここではいくつかのアイデアを紹介します:

  1. オフィス管理: 昔ながらのパンチカードに別れを告げましょう!このシステムは、勤怠管理、オフィスのさまざまなエリアへのアクセス制御、従業員情報の管理方法に革命をもたらします。

  2. セキュリティ システム: オフィスがフォート ノックスであっても、煩わしさがない世界を想像してみてください。この顔認識システムは、堅牢なセキュリティ プロトコルの基礎となります。

  3. 顧客サービス キオスク: これを想像してください。顧客がキオスクに近づくと、顧客が即座に認識され、パーソナライズされたサービスが提供されます。もうSFではありません!

次は何ですか?空には限界がある!

おめでとうございます、テクノロジーの魔術師!顔認証を備えた最先端の従業員ダッシュボードが構築されました。しかし、なぜここで止まるのでしょうか?このシステムの利点はその柔軟性です。次のレベルに引き上げるためのアイデアをいくつか紹介します:

  • 重要な更新に関するリアルタイム通知を実装します
  • 人事向けの詳細レポート機能を追加
  • 給与計算ツールやプロジェクト管理ツールなどの他のシステムと統合します

テクノロジーの世界では、唯一の制限はあなたの想像力 (そしておそらくカフェイン摂取量) だけであることを忘れないでください。

それで、どう思いますか?職場を未来に変える準備はできていますか?このプロジェクトを試してみて、どうなるか教えてください。あなたの経験、追加した素晴らしい機能、または途中で直面した課題についてぜひお聞きください。

コーディングを楽しんでください。そしてあなたの顔認識があなたをオフィスの工場と間違えることがありませんように!

以上が顔認証を使用した安全な従業員ダッシュボードの構築: 包括的な Next.js チュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。