在这篇博文中,我们将指导您逐步将 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中文网其他相关文章!