@devdouglassoares7/face-auth-kit
v0.1.2
Published
Reconhecimento facial plug-and-play (MediaPipe) para autenticação primária ou MFA. Agnóstico de backend via adapters. React + TypeScript.
Maintainers
Readme
👤 face-auth-kit
Reconhecimento facial plug-and-play para React — login por rosto ou MFA. Plug-and-play face recognition for React — face login or MFA. Reconocimiento facial plug-and-play para React — login facial o MFA.
🇧🇷 Português · 🇺🇸 English · 🇪🇸 Español
🔒 Privacidade / Privacy / Privacidad: só a geometria facial (vetor numérico) é usada. Nenhuma foto é capturada ou enviada · No photo is captured or sent · Ninguna foto se captura ni se envía.
pnpm add @devdouglassoares7/face-auth-kit react react-dom🇧🇷 Português
Reconhecimento facial plug-and-play (MediaPipe Face Landmarker) para React. Use como autenticação primária (login por rosto, 1:N) ou como MFA (2º fator após login/senha, 1:1). Agnóstico de backend via adapters — pluga no seu Supabase, Firebase, API própria… Sem CSS/Tailwind, temável e com textos configuráveis (i18n).
✨ Recursos
- 📷 Captura com liveness (piscar) e orientação ("chegue mais perto / afaste / pisque")
- 🔁 Retry automático — não falha na primeira; tenta reconhecer várias vezes
- 🧩 Adapter de backend (1:N login · 1:1 MFA)
- 🧠 Núcleo sem MediaPipe (
/core) — compare rostos no servidor/serverless - 🎨 Temável (
accent), traduzível (labels), zero dependência de CSS
Como funciona
<FaceAuth>abre a câmera, faz liveness e extrai um descriptor (vetor).- O descriptor vai pro seu adapter (
enrollouverify). - O adapter decide onde guardar e como comparar.
Login facial (1:N)
import { FaceAuth, type FaceAuthAdapter } from "@devdouglassoares7/face-auth-kit";
const adapter: FaceAuthAdapter = {
async enroll(userId, descriptor) {
await api.saveFace(userId, descriptor);
},
async verify(descriptor) {
const found = await api.identify(descriptor); // seu backend compara
return found ? { ok: true, userId: found.id, distance: found.dist } : { ok: false, reason: "no_match" };
},
};
<FaceAuth mode="verify" adapter={adapter} onSuccess={signIn} onCancel={close} />MFA (2º fator, 1:1)
// usuário já fez login/senha; o rosto confirma que é ele
<FaceAuth mode="verify" adapter={adapter} userId={user.id} onSuccess={grantAccess} />
// cadastro (uma vez):
<FaceAuth mode="enroll" adapter={adapter} userId={user.id} onSuccess={done} />Comparação no servidor (sem MediaPipe)
import { matchDescriptor } from "@devdouglassoares7/face-auth-kit/core";
const rows = userId ? [await db.getFace(userId)] : await db.getAllFaces();
const m = matchDescriptor(descriptor, rows, { threshold: 0.33 });Configuração
<FaceAuth
mode="verify" adapter={adapter} accent="#8b5cf6"
config={{ captureFrames: 8, requireBlink: true, minCoverage: 0.22, maxCoverage: 0.62, maxVerifyAttempts: 5 }}
labels={{ titleVerify: "Entrar com o rosto" }}
/>🇺🇸 English
Plug-and-play face recognition (MediaPipe Face Landmarker) for React. Use it as primary auth (face login, 1:N) or as MFA (2nd factor after password, 1:1). Backend-agnostic via adapters — plug into Supabase, Firebase, your own API… No CSS/Tailwind, themeable, with configurable strings (i18n).
✨ Features
- 📷 Capture with liveness (blink) and guidance ("move closer / back / blink")
- 🔁 Auto-retry — doesn't fail on the first try; keeps attempting
- 🧩 Backend adapter (1:N login · 1:1 MFA)
- 🧠 MediaPipe-free core (
/core) — match faces on the server/serverless - 🎨 Themeable (
accent), translatable (labels), zero CSS dependency
How it works
<FaceAuth>opens the camera, runs liveness and extracts a descriptor (vector).- The descriptor goes to your adapter (
enrollorverify). - The adapter decides where to store and how to compare.
Face login (1:N)
import { FaceAuth, type FaceAuthAdapter } from "@devdouglassoares7/face-auth-kit";
const adapter: FaceAuthAdapter = {
async enroll(userId, descriptor) { await api.saveFace(userId, descriptor); },
async verify(descriptor) {
const found = await api.identify(descriptor);
return found ? { ok: true, userId: found.id, distance: found.dist } : { ok: false, reason: "no_match" };
},
};
<FaceAuth mode="verify" adapter={adapter} onSuccess={signIn} onCancel={close} />MFA (2nd factor, 1:1)
// user already logged in with password; face confirms it's them
<FaceAuth mode="verify" adapter={adapter} userId={user.id} onSuccess={grantAccess} />
// enroll (once):
<FaceAuth mode="enroll" adapter={adapter} userId={user.id} onSuccess={done} />Server-side match (no MediaPipe)
import { matchDescriptor } from "@devdouglassoares7/face-auth-kit/core";
const rows = userId ? [await db.getFace(userId)] : await db.getAllFaces();
const m = matchDescriptor(descriptor, rows, { threshold: 0.33 });Configuration
<FaceAuth
mode="verify" adapter={adapter} accent="#8b5cf6"
config={{ captureFrames: 8, requireBlink: true, minCoverage: 0.22, maxCoverage: 0.62, maxVerifyAttempts: 5 }}
labels={{ titleVerify: "Sign in with your face" }}
/>🇪🇸 Español
Reconocimiento facial plug-and-play (MediaPipe Face Landmarker) para React. Úsalo como autenticación primaria (login facial, 1:N) o como MFA (2º factor tras contraseña, 1:1). Agnóstico de backend vía adapters — conéctalo a Supabase, Firebase, tu propia API… Sin CSS/Tailwind, con tema y textos configurables (i18n).
✨ Características
- 📷 Captura con liveness (parpadeo) y guía ("acércate / aléjate / parpadea")
- 🔁 Reintento automático — no falla al primer intento; sigue intentando
- 🧩 Adapter de backend (1:N login · 1:1 MFA)
- 🧠 Núcleo sin MediaPipe (
/core) — compara rostros en el servidor/serverless - 🎨 Con tema (
accent), traducible (labels), sin dependencia de CSS
Cómo funciona
<FaceAuth>abre la cámara, hace liveness y extrae un descriptor (vector).- El descriptor va a tu adapter (
enrolloverify). - El adapter decide dónde guardar y cómo comparar.
Login facial (1:N)
import { FaceAuth, type FaceAuthAdapter } from "@devdouglassoares7/face-auth-kit";
const adapter: FaceAuthAdapter = {
async enroll(userId, descriptor) { await api.saveFace(userId, descriptor); },
async verify(descriptor) {
const found = await api.identify(descriptor);
return found ? { ok: true, userId: found.id, distance: found.dist } : { ok: false, reason: "no_match" };
},
};
<FaceAuth mode="verify" adapter={adapter} onSuccess={signIn} onCancel={close} />MFA (2º factor, 1:1)
// el usuario ya inició sesión con contraseña; el rostro confirma que es él
<FaceAuth mode="verify" adapter={adapter} userId={user.id} onSuccess={grantAccess} />
// registro (una vez):
<FaceAuth mode="enroll" adapter={adapter} userId={user.id} onSuccess={done} />Comparación en el servidor (sin MediaPipe)
import { matchDescriptor } from "@devdouglassoares7/face-auth-kit/core";
const rows = userId ? [await db.getFace(userId)] : await db.getAllFaces();
const m = matchDescriptor(descriptor, rows, { threshold: 0.33 });Configuración
<FaceAuth
mode="verify" adapter={adapter} accent="#8b5cf6"
config={{ captureFrames: 8, requireBlink: true, minCoverage: 0.22, maxCoverage: 0.62, maxVerifyAttempts: 5 }}
labels={{ titleVerify: "Entrar con tu rostro" }}
/>📦 API
| Export | |
|---|---|
| FaceAuth | React component (camera + liveness + capture + retry) |
| FaceAuthAdapter | Backend interface (enroll, verify, remove?) |
| createMemoryAdapter() | Reference/in-memory adapter (demos & tests) |
| @devdouglassoares7/face-auth-kit/core | No React/MediaPipe: matchDescriptor, euclideanDistance, averageDescriptors, robustAverage, FACE_DESCRIPTOR_LENGTH |
| browser core | loadFaceModels, detectFace, computeDescriptor, faceCoverage, isBlinking |
📄 License
MIT © Douglas Soares
