a
This commit is contained in:
parent
21c76eab9b
commit
d12b187350
|
|
@ -1,4 +1,8 @@
|
|||
<?php
|
||||
/**
|
||||
* API Backend pour la vérification faciale
|
||||
* Gère la validation des tokens et la comparaison des visages
|
||||
*/
|
||||
|
||||
session_start();
|
||||
|
||||
|
|
@ -9,39 +13,46 @@ class FacialVerificationAPI {
|
|||
private $maxAttempts = 3;
|
||||
|
||||
public function __construct() {
|
||||
/*
|
||||
$this->assure_api = $_SESSION['assure'];
|
||||
$this->maxAttempts = $this->assure_api->get_nbTentativeBiometrie($_SESSION['codeEntite']);
|
||||
*/
|
||||
$this->assure_api = $_SESSION['assure']; // ✅ $this->
|
||||
$this->maxAttempts = $this->assure_api->get_nbTentativeBiometrie($_SESSION['codeEntite']); // ✅ $this->
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Valide un token de vérification
|
||||
*/
|
||||
public function validateToken($token) {
|
||||
return ['success' => false, 'message' => "TESTS KANE"];
|
||||
/*
|
||||
try {
|
||||
$request = $this->assure_api->valider_token(); // ✅ une seule fois, dans le try
|
||||
$request = $this->assure_api->valider_token(); // ✅ une seule fois, dans le try
|
||||
|
||||
if (!$request) {
|
||||
return ['success' => false, 'message' => 'Lien expiré ou invalide'];
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Lien expiré ou invalide'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => 'Token valide',
|
||||
'assure' => [
|
||||
'assure' => [
|
||||
'nom' => $request['nom'],
|
||||
'prenoms' => $request['prenoms']
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur validateToken: " . $e->getMessage());
|
||||
return ['success' => false, 'message' => 'Erreur serveur'];
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Erreur serveur'
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* Compare deux visages avec l'API de reconnaissance faciale
|
||||
* Utilisez Azure Face API, AWS Rekognition, ou une solution locale
|
||||
*/
|
||||
private function compareFaces($referenceImagePath, $capturedImageBase64) {
|
||||
// Option 1: Azure Face API (Recommandé)
|
||||
return $this->compareWithAzureFaceAPI($referenceImagePath, $capturedImageBase64);
|
||||
|
|
@ -53,32 +64,35 @@ class FacialVerificationAPI {
|
|||
// return $this->compareWithLocalFaceRecognition($referenceImagePath, $capturedImageBase64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparaison avec Azure Face API
|
||||
*/
|
||||
private function compareWithAzureFaceAPI($referenceImagePath, $capturedImageBase64) {
|
||||
$endpoint = AZURE_FACE_ENDPOINT; // Ex: https://your-resource.cognitiveservices.azure.com
|
||||
$apiKey = AZURE_FACE_API_KEY;
|
||||
$endpoint = AZURE_FACE_ENDPOINT;
|
||||
$apiKey = AZURE_FACE_API_KEY;
|
||||
|
||||
try {
|
||||
// 1. Détecter le visage dans l'image de référence
|
||||
$referenceImageData = base64_encode(file_get_contents($referenceImagePath));
|
||||
$referenceFaceId = $this->detectFaceAzure($referenceImageData, $endpoint, $apiKey);
|
||||
$referenceFaceId = $this->detectFaceAzure($referenceImageData, $endpoint, $apiKey);
|
||||
|
||||
if (!$referenceFaceId) {
|
||||
return [
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'confidence' => 0,
|
||||
'error' => 'Aucun visage détecté dans la photo de référence'
|
||||
'error' => 'Aucun visage détecté dans la photo de référence'
|
||||
];
|
||||
}
|
||||
|
||||
// 2. Détecter le visage dans l'image capturée
|
||||
$capturedImageData = explode(',', $capturedImageBase64)[1]; // Enlever le préfixe data:image
|
||||
$capturedFaceId = $this->detectFaceAzure($capturedImageData, $endpoint, $apiKey);
|
||||
$capturedImageData = explode(',', $capturedImageBase64)[1];
|
||||
$capturedFaceId = $this->detectFaceAzure($capturedImageData, $endpoint, $apiKey);
|
||||
|
||||
if (!$capturedFaceId) {
|
||||
return [
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'confidence' => 0,
|
||||
'error' => 'Aucun visage détecté dans votre photo'
|
||||
'error' => 'Aucun visage détecté dans votre photo'
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -110,21 +124,24 @@ class FacialVerificationAPI {
|
|||
$result = json_decode($response, true);
|
||||
|
||||
return [
|
||||
'match' => $result['isIdentical'],
|
||||
'match' => $result['isIdentical'],
|
||||
'confidence' => round($result['confidence'] * 100, 2),
|
||||
'error' => null
|
||||
'error' => null
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur Azure Face API: " . $e->getMessage());
|
||||
return [
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'confidence' => 0,
|
||||
'error' => 'Erreur lors de la vérification faciale'
|
||||
'error' => 'Erreur lors de la vérification faciale'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Détecte un visage avec Azure Face API et retourne le faceId
|
||||
*/
|
||||
private function detectFaceAzure($imageBase64, $endpoint, $apiKey) {
|
||||
$detectUrl = $endpoint . '/face/v1.0/detect?returnFaceId=true';
|
||||
|
||||
|
|
@ -154,54 +171,60 @@ class FacialVerificationAPI {
|
|||
return $faces[0]['faceId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparaison avec AWS Rekognition (Alternative)
|
||||
*/
|
||||
private function compareWithAWSRekognition($referenceImagePath, $capturedImageBase64) {
|
||||
require_once 'vendor/autoload.php'; // AWS SDK
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
try {
|
||||
$rekognitionClient = new Aws\Rekognition\RekognitionClient([
|
||||
'version' => 'latest',
|
||||
'region' => AWS_REGION,
|
||||
'version' => 'latest',
|
||||
'region' => AWS_REGION,
|
||||
'credentials' => [
|
||||
'key' => AWS_ACCESS_KEY_ID,
|
||||
'key' => AWS_ACCESS_KEY_ID,
|
||||
'secret' => AWS_SECRET_ACCESS_KEY
|
||||
]
|
||||
]);
|
||||
|
||||
$referenceImageData = file_get_contents($referenceImagePath);
|
||||
$capturedImageData = base64_decode(explode(',', $capturedImageBase64)[1]);
|
||||
$capturedImageData = base64_decode(explode(',', $capturedImageBase64)[1]);
|
||||
|
||||
$result = $rekognitionClient->compareFaces([
|
||||
'SourceImage' => ['Bytes' => $referenceImageData],
|
||||
'TargetImage' => ['Bytes' => $capturedImageData],
|
||||
'SourceImage' => ['Bytes' => $referenceImageData],
|
||||
'TargetImage' => ['Bytes' => $capturedImageData],
|
||||
'SimilarityThreshold' => 80
|
||||
]);
|
||||
|
||||
if (empty($result['FaceMatches'])) {
|
||||
return [
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'confidence' => 0,
|
||||
'error' => 'Les visages ne correspondent pas'
|
||||
'error' => 'Les visages ne correspondent pas'
|
||||
];
|
||||
}
|
||||
|
||||
$similarity = $result['FaceMatches'][0]['Similarity'];
|
||||
|
||||
return [
|
||||
'match' => $similarity >= 80,
|
||||
'match' => $similarity >= 80,
|
||||
'confidence' => round($similarity, 2),
|
||||
'error' => null
|
||||
'error' => null
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur AWS Rekognition: " . $e->getMessage());
|
||||
return [
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'confidence' => 0,
|
||||
'error' => 'Erreur lors de la vérification faciale'
|
||||
'error' => 'Erreur lors de la vérification faciale'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistre la photo capturée
|
||||
*/
|
||||
private function saveCapturedImage($assureId, $imageBase64) {
|
||||
$uploadDir = 'uploads/facial_verification/';
|
||||
|
||||
|
|
@ -218,6 +241,9 @@ class FacialVerificationAPI {
|
|||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour le statut de la vérification
|
||||
*/
|
||||
private function updateVerificationStatus($token, $status, $matchResult = null, $capturedPhotoPath = null) {
|
||||
$sql = "UPDATE facial_verification_requests
|
||||
SET status = ?,
|
||||
|
|
@ -236,9 +262,12 @@ class FacialVerificationAPI {
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une session d'autorisation pour l'accès aux prestations
|
||||
*/
|
||||
private function createAuthorizationSession($assureId, $verificationRequestId) {
|
||||
$sessionToken = bin2hex(random_bytes(32));
|
||||
$expiresAt = date('Y-m-d H:i:s', time() + 3600); // 1 heure
|
||||
$expiresAt = date('Y-m-d H:i:s', time() + 3600);
|
||||
|
||||
$sql = "INSERT INTO prestation_authorization_sessions
|
||||
(assure_id, verification_request_id, session_token, expires_at, status)
|
||||
|
|
@ -250,6 +279,9 @@ class FacialVerificationAPI {
|
|||
return $sessionToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie le visage capturé
|
||||
*/
|
||||
public function verifyFace($token, $capturedImageBase64) {
|
||||
try {
|
||||
// 1. Récupérer les infos de la demande
|
||||
|
|
@ -267,7 +299,7 @@ class FacialVerificationAPI {
|
|||
if (!$request) {
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'message' => 'Demande expirée ou invalide'
|
||||
];
|
||||
}
|
||||
|
|
@ -277,7 +309,7 @@ class FacialVerificationAPI {
|
|||
$this->updateVerificationStatus($token, 'failed');
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'message' => 'Nombre maximum de tentatives atteint'
|
||||
];
|
||||
}
|
||||
|
|
@ -294,50 +326,48 @@ class FacialVerificationAPI {
|
|||
if ($comparisonResult['error']) {
|
||||
$this->updateVerificationStatus($token, 'error', $comparisonResult, $capturedPhotoPath);
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'message' => $comparisonResult['error'],
|
||||
'attempts_remaining' => $this->maxAttempts - ($request['attempts'] + 1)
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'message' => $comparisonResult['error'],
|
||||
'attempts_remaining'=> $this->maxAttempts - ($request['attempts'] + 1)
|
||||
];
|
||||
}
|
||||
|
||||
// 5. Seuil de confiance minimum (ex: 80%)
|
||||
// 5. Seuil de confiance minimum (80%)
|
||||
$confidenceThreshold = 80;
|
||||
$isMatch = $comparisonResult['match'] && $comparisonResult['confidence'] >= $confidenceThreshold;
|
||||
|
||||
if ($isMatch) {
|
||||
// Succès: créer une session d'autorisation
|
||||
$this->updateVerificationStatus($token, 'verified', $comparisonResult, $capturedPhotoPath);
|
||||
$sessionToken = $this->createAuthorizationSession($request['assure_id'], $request['id']);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'match' => true,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Identité vérifiée avec succès',
|
||||
'success' => true,
|
||||
'match' => true,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Identité vérifiée avec succès',
|
||||
'session_token' => $sessionToken,
|
||||
'redirect_url' => 'saisie_prestations.php?token=' . $sessionToken
|
||||
'redirect_url' => 'saisie_prestations.php?token=' . $sessionToken
|
||||
];
|
||||
} else {
|
||||
// Échec de correspondance
|
||||
$attemptsRemaining = $this->maxAttempts - ($request['attempts'] + 1);
|
||||
|
||||
if ($attemptsRemaining > 0) {
|
||||
$this->updateVerificationStatus($token, 'pending', $comparisonResult, $capturedPhotoPath);
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Votre visage ne correspond pas',
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Votre visage ne correspond pas',
|
||||
'attempts_remaining' => $attemptsRemaining
|
||||
];
|
||||
} else {
|
||||
$this->updateVerificationStatus($token, 'failed', $comparisonResult, $capturedPhotoPath);
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Vérification échouée. Nombre maximum de tentatives atteint.',
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'confidence' => $comparisonResult['confidence'],
|
||||
'message' => 'Vérification échouée. Nombre maximum de tentatives atteint.',
|
||||
'attempts_remaining' => 0
|
||||
];
|
||||
}
|
||||
|
|
@ -347,17 +377,16 @@ class FacialVerificationAPI {
|
|||
error_log("Erreur verifyFace: " . $e->getMessage());
|
||||
return [
|
||||
'success' => false,
|
||||
'match' => false,
|
||||
'match' => false,
|
||||
'message' => 'Erreur lors de la vérification: ' . $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Traiter la requête
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$action = $input['action'] ?? null;
|
||||
|
||||
$api = new FacialVerificationAPI();
|
||||
|
|
@ -388,4 +417,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user