在這篇部落格文章中,我們將引導您逐步將 FACEIO 的人臉身份驗證合併到 Next.js 應用程式中,從設定 FACEIO 帳戶到在程式碼庫中實現整合。
先決條件
在我們深入之前,請確保您已準備好以下內容:
Node.js 和 npm:確保您的開發電腦上安裝了 Node.js 和 npm。您可以從 Node.js 官方網站下載最新版本。
Next.js:您需要設定一個 Next.js 專案。如果您沒有,您可以建立一個新的:
設定 FACEIO 應用程式
1.建立新的 FACEIO 應用程式:登入您的 FACEIO 控制台並點擊「建立新應用程式」按鈕。
2.設定應用程式:填寫所需信息,例如應用程式名稱、描述和回調 URL(這將是您的 Next.js 應用程式的 URL)。填寫完表格後,點選「建立應用程式」。
3.取得FACEIO_APP_ID:建立應用程式後,您將獲得一個唯一的FACEIO_APP_ID。這是您將用於將 FACEIO 整合到 Next.js 應用程式中的識別碼。
將 FACEIO 整合到您的 Next.js 應用程式
1.安裝 FACEIO NPM 套件:在 Next.js 專案中,使用 npm 或 YARN 安裝 Faceio-npm 套件:
2.建立人臉驗證元件:在您的Next.js 專案中,使用以下程式碼建立一個名為Components/Dashboard.tsx(或您喜歡的任何其他名稱)的新文件:
// Dashboard.tsx import React from "react"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { FaUserCircle, FaLock, FaCode, FaChartBar, FaSignOutAlt } from 'react-icons/fa'; interface DashboardProps { userEmail: string; onLogout: () => void; } const Dashboard: React.FC<DashboardProps> = ({ userEmail, onLogout }) => { return ( <div className="max-w-7xl mx-auto p-4 md:p-6 space-y-6"> <Card className="w-full bg-black text-white"> <CardHeader className="flex flex-col sm:flex-row items-start sm:items-center justify-between space-y-4 sm:space-y-0"> <div> <CardTitle className="text-2xl sm:text-3xl font-bold">Welcome to FaceIO</CardTitle> <p className="text-base sm:text-lg mt-2">Email: {userEmail}</p> </div> <Button variant="secondary" size="sm" onClick={onLogout} className="flex items-center w-full sm:w-auto justify-center mt-8" > <FaSignOutAlt className="mr-2" /> Logout </Button> </CardHeader> <CardContent> <p className="text-lg sm:text-xl mb-4">You have successfully logged in.</p> </CardContent> </Card> <h2 className="text-xl sm:text-2xl font-bold text-center my-6">Facial Authentication for the Web</h2> <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6"> <Card> <CardHeader> <CardTitle className="flex items-center text-base sm:text-lg"> <FaUserCircle className="mr-2" /> Secure & Easy </CardTitle> </CardHeader> <CardContent> <p className="text-sm sm:text-base">Cross-browser, secure & easy to implement. Passwordless Authentication SDKs powered by Face Recognition for Web Sites & Apps.</p> </CardContent> </Card> <Card> <CardHeader> <CardTitle className="flex items-center text-base sm:text-lg"> <FaLock className="mr-2" /> Privacy-Focused </CardTitle> </CardHeader> <CardContent> <p className="text-sm sm:text-base">Your facial data is encrypted and securely stored. We prioritize user privacy and data protection.</p> </CardContent> </Card> <Card> <CardHeader> <CardTitle className="flex items-center text-base sm:text-lg"> <FaCode className="mr-2" /> Developer-Friendly </CardTitle> </CardHeader> <CardContent> <p className="text-sm sm:text-base">Easy integration with clear documentation. Get started quickly and implement facial authentication in your projects.</p> </CardContent> </Card> <Card> <CardHeader> <CardTitle className="flex items-center text-base sm:text-lg"> <FaChartBar className="mr-2" /> Analytics & Insights </CardTitle> </CardHeader> <CardContent> <p className="text-sm sm:text-base">Gain valuable insights into user authentication patterns and improve your applications security.</p> </CardContent> </Card> </div> <div className="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8"> <Button variant="default" size="lg" className="w-full sm:w-auto"> Get Started → </Button> <Button variant="outline" size="lg" className="w-full sm:w-auto"> Integration Guide → </Button> <Button variant="secondary" size="lg" className="w-full sm:w-auto"> FACEIO Console → </Button> </div> <Card className="mt-8 bg-gray-100"> <CardContent className="text-center py-6"> <p className="text-base sm:text-lg font-semibold">Ready to implement facial authentication in your project?</p> <p className="mt-2 text-sm sm:text-base">Check out our documentation and start securing your application today!</p> </CardContent> </Card> </div> ); }; export default Dashboard;
3.將 Dashboard.tsx 元件導入 Login.tsx 元件:
/* eslint-disable react-hooks/exhaustive-deps */ "use client"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Terminal } from "lucide-react"; import { MailIcon, CheckCircleIcon } from "lucide-react"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Button } from "./ui/button"; import faceIO from "@faceio/fiojs"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import { toast } from "sonner"; import Dashboard from "./Dashboard"; type Props = {}; const Login: React.FC<Props> = ({}) => { const faceioRef = useRef<faceIO | null>(null); const [email, setEmail] = useState(""); const [userLogin, setUserLogin] = useState(""); const [isLoggedIn, setIsLoggedIn] = useState(false); const publicKey = process.env.NEXT_PUBLIC_FACEIO_PUBLIC_ID as string; const initialiseFaceio = async () => { try { faceioRef.current = new faceIO(publicKey); console.log("FaceIO initialized successfully"); } catch (error) { console.log(error); handleError(error); } }; useEffect(() => { initialiseFaceio(); }, []); const handleRegister = async () => { try { if (!faceioRef.current) { console.error("FaceIO instance is not initialized"); return; } await faceioRef.current?.enroll({ userConsent: false, locale: "auto", payload: { email: `${email}` }, }); toast.success("Successfully Registered user."); } catch (error) { handleError(error); faceioRef.current?.restartSession(); } }; const handleLogin = async () => { try { const authenticate = await faceioRef.current?.authenticate(); console.log("User authenticated successfully:", authenticate); setUserLogin(authenticate.payload.email); setIsLoggedIn(true); toast.success("Successfully logged in."); } catch (error) { console.log(error); handleError(error); } }; const handleLogout = () => { setIsLoggedIn(false); setUserLogin(""); toast.success("Successfully logged out."); }; function handleError(errCode: any) { const fioErrs = faceioRef.current?.fetchAllErrorCodes()!; switch (errCode) { case fioErrs.PERMISSION_REFUSED: toast.info("Access to the Camera stream was denied by the end user"); break; case fioErrs.NO_FACES_DETECTED: toast.info( "No faces were detected during the enroll or authentication process" ); break; case fioErrs.UNRECOGNIZED_FACE: toast.info("Unrecognized face on this application's Facial Index"); break; case fioErrs.MANY_FACES: toast.info("Two or more faces were detected during the scan process"); break; case fioErrs.FACE_DUPLICATION: toast.info( "User enrolled previously (facial features already recorded). Cannot enroll again!" ); break; case fioErrs.MINORS_NOT_ALLOWED: toast.info("Minors are not allowed to enroll on this application!"); break; case fioErrs.PAD_ATTACK: toast.info( "Presentation (Spoof) Attack (PAD) detected during the scan process" ); break; case fioErrs.FACE_MISMATCH: toast.info( "Calculated Facial Vectors of the user being enrolled do not matches" ); break; case fioErrs.WRONG_PIN_CODE: toast.info("Wrong PIN code supplied by the user being authenticated"); break; case fioErrs.PROCESSING_ERR: toast.info("Server side error"); break; case fioErrs.UNAUTHORIZED: toast.info( "Your application is not allowed to perform the requested operation (eg. Invalid ID, Blocked, Paused, etc.). Refer to the FACEIO Console for additional information" ); break; case fioErrs.TERMS_NOT_ACCEPTED: toast.info( "Terms & Conditions set out by FACEIO/host application rejected by the end user" ); break; case fioErrs.UI_NOT_READY: toast.info( "The FACEIO Widget could not be (or is being) injected onto the client DOM" ); break; case fioErrs.SESSION_EXPIRED: toast.info( "Client session expired. The first promise was already fulfilled but the host application failed to act accordingly" ); break; case fioErrs.TIMEOUT: toast.info( "Ongoing operation timed out (eg, Camera access permission, ToS accept delay, Face not yet detected, Server Reply, etc.)" ); break; case fioErrs.TOO_MANY_REQUESTS: toast.info( "Widget instantiation requests exceeded for freemium applications. Does not apply for upgraded applications" ); break; case fioErrs.EMPTY_ORIGIN: toast.info("Origin or Referer HTTP request header is empty or missing"); break; case fioErrs.FORBIDDDEN_ORIGIN: toast.info("Domain origin is forbidden from instantiating fio.js"); break; case fioErrs.FORBIDDDEN_COUNTRY: toast.info( "Country ISO-3166-1 Code is forbidden from instantiating fio.js" ); break; case fioErrs.SESSION_IN_PROGRESS: toast.info( "Another authentication or enrollment session is in progress" ); break; case fioErrs.NETWORK_IO: default: toast.info( "Error while establishing network connection with the target FACEIO processing node" ); break; } } if (isLoggedIn) { return <Dashboard userEmail={userLogin} onLogout={handleLogout} />; } return ( <div className="min-h-screen bg-gradient-to-r from-cyan-500 to-blue-500 flex items-center justify-center p-4 w-full"> <Card className="w-[400px] bg-white shadow-xl rounded-xl overflow-hidden"> <CardHeader className="bg-gray-50 border-b p-6"> <CardTitle className="text-2xl font-bold text-gray-800"> Secure Workspace </CardTitle> <CardDescription className="text-sm text-gray-600"> Authenticate to access your personalized work environment </CardDescription> </CardHeader> <CardContent className="p-6 space-y-4"> <div className="space-y-2"> <Label htmlFor="email" className="text-sm font-medium text-gray-700" > Work Email </Label> <Input id="email" type="email" placeholder="you@company.com" className="w-full px-3 py-2 border rounded-md" onChange={(e) => setEmail(e.target.value)} /> </div> <div className="space-y-4"> <Button className="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 rounded-md transition duration-300 ease-in-out" onClick={handleLogin} > Access Workspace </Button> <Button className="w-full bg-gray-100 hover:bg-gray-200 text-gray-800 font-medium py-2 rounded-md transition duration-300 ease-in-out" onClick={handleRegister} disabled={!email.includes("@")} > Register New Account </Button> </div> </CardContent> <CardFooter className="bg-gray-50 border-t p-4"> <div className="w-full text-center text-xs text-gray-500"> Protected by FaceIO™ Technology. <Link href="https://faceio.net/security-policy" className="text-blue-600 hover:underline ml-1" > Learn about our security measures </Link> </div> </CardFooter> </Card> {userLogin && !isLoggedIn && ( <div className="fixed bottom-4 right-4 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-md shadow-lg"> <div className="flex"> <div className="flex-shrink-0"> <CheckCircleIcon className="h-5 w-5 text-green-500" /> </div> <div className="ml-3"> <p className="text-sm font-medium">Workspace Access Granted</p> <p className="text-xs mt-1">Logged in as: {userLogin}</p> </div> </div> </div> )} </div> ); }; export default Login;
請記得將「NEXT_PUBLIC_FACEIO_PUBLIC_ID」替換為您從 FACEIO 控制台取得的實際 FACEIO_APP_ID。
import { buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import Link from "next/link"; import { FaUserShield, FaImage, FaCode, FaRobot } from 'react-icons/fa'; export default function Home() { const demos = [ { title: "FACIO Web Authentication", href: "/faceio", icon: FaUserShield }, { title: "Image Processing", href: "/imageprocessing", icon: FaImage }, { title: "Code Generation", href: "/codegeneration", icon: FaCode }, { title: "AI Assistant", href: "/aiassistant", icon: FaRobot }, ]; return ( <div className="max-h-screen bg-gradient-to-br from-purple-700 via-blue-600 to-teal-500 text-white p-8 w-full"> <div className="max-w-6xl mx-auto"> <h1 className="text-5xl md:text-7xl font-bold text-center mb-8 animate-fade-in-down"> PixLab Faceio </h1> <p className="text-xl text-center mb-12 animate-fade-in-up"> Explore cutting-edge technologies and innovative solutions </p> <div className="grid grid-cols-1 md:grid-cols-2 gap-8"> {demos.map((demo, index) => ( <Link key={demo.href} href={demo.href} className={cn( buttonVariants({ variant: "outline" }), "h-40 text-lg font-semibold flex flex-col items-center justify-center space-y-4 bg-white bg-opacity-10 backdrop-filter backdrop-blur-lg rounded-xl hover:bg-opacity-20 transition-all duration-300 animate-fade-in", { 'animate-delay-100': index % 2 === 1 } )} > <demo.icon className="text-4xl" /> {demo.title} </Link> ))} </div> <div className="mt-16 text-center animate-fade-in-up animate-delay-300"> <h2 className="text-3xl font-bold mb-4">Why Choose PixLab?</h2> <ul className="text-lg space-y-2"> <li>✨ Cutting-edge technologies</li> <li>? High-performance solutions</li> <li>? Advanced security features</li> <li>? Seamless integrations</li> </ul> </div> <footer className="mt-16 text-center text-sm opacity-75 animate-fade-in-up animate-delay-500"> © 2024 PixLab. All rights reserved. Empowering innovation through technology. </footer> </div> </div> ); }
就是這樣!現在您已將 FACEIO 的人臉身份驗證整合到您的 Next.js 應用程式中。當使用者點擊「臉部驗證」按鈕時,FACEIO 小工具將會出現,引導他們完成身份驗證過程。
捕捉正在運行的 FACEIO 小部件 - 註冊
為了示範 FACEIO 小工具的功能,讓我們捕捉註冊過程的 GIF:
此 GIF 展示了 Next.js 應用程式中 FACEIO 人臉註冊過程的使用者體驗。使用者可以輕鬆註冊自己的臉部,以用於將來登入時的無縫身份驗證。
捕捉正在運行的 FACEIO 小部件
為了示範 FACEIO 小工具的功能,讓我們捕捉身份驗證過程的 GIF:
此 GIF 展示了 Next.js 應用程式中 FACEIO 人臉身份驗證過程的使用者體驗。
FACEIO 應用程式的關鍵安全最佳實踐
消除重複註冊:啟用設定以阻止同一用戶多次註冊,避免潛在的衝突或誤用。
增強反欺騙措施:啟動偵測和阻止人臉欺騙嘗試的功能,確保系統僅與真實的使用者互動。
保證 PIN 唯一性:確保每個使用者的 PIN 在應用程式中是唯一的,以防止未經授權的存取。
實施地理限制:將 FACEIO 小部件的實例化限制為授權域名和國家/地區,以增強安全控制。
在 Next.js 應用中使用 FACEIO 的好處
將 FACEIO 整合到您的 Next.js 應用程式中具有以下幾個好處:
改進的使用者體驗:FACEIO 小工具提供無縫且直覺的驗證流程,使用戶可以輕鬆登入您的應用程式。
跨平台相容性:FACEIO 可跨各種裝置和瀏覽器運作,確保一致的使用者體驗。
輕鬆整合:faceio-npm 套件簡化了整合過程,讓您快速將人臉驗證新增至 Next.js 應用程式。
FACEIO 社群論壇:您可以從 FACEIO 社群獲得問題協助。
結論
在這篇文章中,您學習如何將 FACEIO 的人臉身份驗證服務整合到您的 Next.js 應用程式中。透過執行此處概述的步驟,您現在可以為使用者提供安全且使用者友好的身份驗證體驗,從而提高 Web 應用程式的整體品質。
如果您有任何其他問題或需要其他協助,請隨時聯絡 FACEIO 支援團隊或瀏覽全面的 FACEIO 文件。
編碼愉快!
要取得此實作的完整原始碼,您可以存取 GitHub 儲存庫並詳細探索該專案。
以上是使用 FACEIO 在 Next.js 應用程式中進行無縫人臉身份驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!