assure/Contestation/verify_facial_api.php
2026-02-24 05:57:08 +00:00

292 lines
10 KiB
PHP

<?php
ob_start();
require_once "Assure.php";
session_start();
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
ob_end_clean();
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
exit;
}
class FacialVerificationAPI {
private $assure_api;
private $maxAttempts = 3;
public function __construct() {
$this->assure_api = $_SESSION['assure'];
$this->maxAttempts = $this->assure_api
? $this->assure_api->get_nbTentativeBiometrie($_SESSION['codeEntite'])
: 3;
}
/**
* Valide un token de vérification
*/
public function validateToken($token) {
$_SESSION['lienPhoto'] = "";
try {
$request = $this->assure_api->valider_token();
if (!$request) {
return [
'success' => false,
'message' => 'Lien expiré ou invalide'
];
}
$_SESSION['lienPhoto'] = $request['lienPhoto'];
return [
'success' => true,
'message' => 'Token valide',
'assure' => [
'nom' => $request['nom'],
'prenoms' => $request['prenoms']
]
];
} catch (Exception $e) {
error_log("Erreur validateToken: " . $e->getMessage());
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) {
//AWS Rekognition
return $this->compareWithAWSRekognition($referenceImagePath, $capturedImageBase64);
}
/**
* Comparaison avec AWS Rekognition (Alternative)
*/
private function compareWithAWSRekognition($referenceImagePath, $capturedImageBase64) {
require_once 'vendor/autoload.php';
try {
$rekognitionClient = new Aws\Rekognition\RekognitionClient([
'version' => 'latest',
'region' => 'us-west-2',
'credentials' => [
'key' => 'AKIA2O2PTXQ7XN5OATO3',
'secret' => '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'
]
]);
$referenceImageData = $referenceImagePath;
$capturedImageData = $capturedImageBase64;
$this->assure_api->init_traiterlaface('2');
$result = $rekognitionClient->compareFaces([
'SourceImage' => ['Bytes' => base64_decode($capturedImageData)],
'TargetImage' => ['Bytes' => base64_decode($referenceImageData)],
'SimilarityThreshold' => 80
]);
if (empty($result['FaceMatches'])) {
$this->assure_api->resultat_traitement_face($_SESSION['numeroBeneficiaire'], '0', "Les faces ne correspondent pas! / The faces do not match!");
return [
'match' => false,
'confidence' => 0,
'error' => 'Les visages ne correspondent pas'
];
}
$similarity = $result['FaceMatches'][0]['Similarity'];
// Face confirmée! / Face confirmed!
$this->assure_api->resultat_traitement_face($_SESSION['numeroBeneficiaire'], '1', '');
return [
'match' => $similarity >= 80,
'confidence' => round($similarity, 2),
'error' => null
];
} catch (Exception $e) {
$this->assure_api->resultat_traitement_face($_SESSION['numeroBeneficiaire'], '9', $msgErreur);
return [
'match' => false,
'confidence' => 0,
'error' => 'Erreur lors de la vérification faciale',
'error_kane' => $e->getMessage(),
];
}
}
/**
* Enregistre la photo capturée
*/
private function saveCapturedImage($assureId, $imageBase64) {
$uploadDir = 'uploads/facial_verification/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$imageData = base64_decode($imageBase64);
$filename = $uploadDir . $assureId . '_' . time() . '.jpg';
file_put_contents($filename, $imageData);
return $filename;
}
/**
* Vérifie le visage capturé
*/
public function verifyFace($token, $capturedImageBase64) {
try {
// 1. Récupérer les infos de la demande
$request = $this->assure_api->valider_token();
if (!$request) {
return [
'success' => false,
'match' => false,
'message' => 'Demande expirée ou invalide'
];
}
// 2. Vérifier le nombre de tentatives
if ($request['attempts'] >= $this->maxAttempts) {
$this->assure_api->maj_demandereconnaissancefaciale("2"); // Echec
return [
'success' => false,
'match' => false,
'message' => 'Nombre maximum de tentatives atteint'
];
}
// 3. Enregistrer la photo capturée
$capturedPhotoPath = $this->saveCapturedImage($request['idBeneficiaire'], $capturedImageBase64);
// 4. Comparer les visages
$comparisonResult = $this->compareFaces(
$_SESSION['photoAssureCrypte'],
$capturedImageBase64
);
if ($comparisonResult['error']) {
$this->assure_api->maj_demandereconnaissancefaciale("2"); // Echec
return [
'success' => false,
'match' => false,
'message' => $comparisonResult['error'],
// 'attempts_remaining'=> $this->maxAttempts - ($request['attempts'] + 1)
'attempts_remaining'=> $this->maxAttempts - $request['attempts'])
];
}
// 5. Seuil de confiance minimum (80%)
$confidenceThreshold = 80;
$isMatch = $comparisonResult['match'] && $comparisonResult['confidence'] >= $confidenceThreshold;
if ($isMatch) {
$this->assure_api->maj_demandereconnaissancefaciale("1"); // Vérifié
return [
'success' => true,
'match' => true,
'confidence' => $comparisonResult['confidence'],
'message' => 'Identité vérifiée avec succès',
];
} else {
$attemptsRemaining = $this->maxAttempts - ($request['attempts'] + 1);
if ($attemptsRemaining > 0) {
$this->assure_api->maj_demandereconnaissancefaciale("1"); // En attente
return [
'success' => false,
'match' => false,
'confidence' => $comparisonResult['confidence'],
'message' => 'Votre visage ne correspond pas',
'attempts_remaining' => $attemptsRemaining
];
} else {
$this->assure_api->maj_demandereconnaissancefaciale("2"); // Echec
return [
'success' => false,
'match' => false,
'confidence' => $comparisonResult['confidence'],
'message' => 'Vérification échouée. Nombre maximum de tentatives atteint.',
'attempts_remaining' => 0
];
}
}
} catch (Exception $e) {
error_log("Erreur verifyFace: " . $e->getMessage());
return [
'success' => false,
'match' => false,
'message' => 'Erreur lors de la vérification: ' . $e->getMessage()
];
}
// On supprime le fichier de capture caméra
if($capturedPhotoPath){
@unlink($capturedPhotoPath);
}
}
}
// Traiter la requête
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? null;
$api = new FacialVerificationAPI();
switch ($action) {
case 'validate_token':
$token = $input['token'] ?? null;
if (!$token) {
echo json_encode(['success' => false, 'message' => 'Token requis']);
exit;
}
echo json_encode($api->validateToken($token));
break;
case 'verify_face':
$token = $input['token'] ?? null;
$image = $input['image'] ?? null;
if (!$token || !$image) {
echo json_encode(['success' => false, 'message' => 'Token et image requis']);
exit;
}
echo json_encode($api->verifyFace($token, $image));
break;
default:
echo json_encode(['success' => false, 'message' => 'Action invalide']);
}
} else {
// echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
ob_end_clean(); // ✅ vide le buffer avant d'envoyer le JSON
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
}