production/Controleur/ControleurTesterreconnaissancefaciale_sav.php
2025-12-02 11:29:44 +00:00

351 lines
11 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once 'Framework/Controleur.php';
require_once 'Modele/Societeusercentral.php';
require_once 'Modele/Menuvueutilisateur.php';
class ControleurTesterreconnaissancefaciale extends Controleur {
private $menuvue;
private $societeusercentral;
public function __construct()
{
$this->menuvue = new Menuvueutilisateur();
$this->menuvue->getMenuVue('Testerreconnaissancefaciale');
$this->societeusercentral = new societeusercentral();
}
public function index()
{
$codeSociete = $_SESSION['codeSociete'];
// $paramreconnaissancefaciale = $this->societeusercentral->getSocieteusersReconnaissanceFaciale($codeSociete);
// $this->genererVue(array('paramreconnaissancefaciale' => $paramreconnaissancefaciale));
$this->genererVue();
}
public function diditverifyandmatch(
string $apiKey,
string $selfie,
string $reference,
float $minLiveScore = 0.80, // ex: 0.80 (=80%) liveness pass
float $minFaceScore = 75.0 // ex: 75/100 face match pass
): array {
// 1) Passive Liveness
$livePayload = buildImagePayload($selfie, 'image'); // 'image' ou 'image_base64'
$liveResp = diditpostjson(
'https://verification.didit.me/v2/passive-liveness/',
$apiKey,
$livePayload
);
$liveScore = $liveResp['liveness']['score'] ?? null; // valeur typique 0..1
$liveStatus = $liveResp['liveness']['status'] ?? null; // e.g. Approved/Rejected/In Review
if (!is_numeric($liveScore)) {
throw new RuntimeException('Réponse Liveness invalide: score manquant');
}
if ($liveScore < $minLiveScore || (is_string($liveStatus) && stripos($liveStatus, 'rejected') !== false)) {
return [
'success' => false,
'stage' => 'liveness',
'reason' => 'fail_threshold',
'details' => [
'score' => $liveScore,
'status' => $liveStatus,
'min_required' => $minLiveScore,
],
];
}
// 2) Face Match 1:1 (selfie validé vs référence)
$matchPayload = buildImagePayload($selfie, 'source', true) +
buildImagePayload($reference, 'target', true);
$matchResp = diditpostjson(
'https://verification.didit.me/v2/face-match/',
$apiKey,
$matchPayload
);
$faceScore = $matchResp['face_match']['score'] ?? null; // 0..100
$faceStatus = $matchResp['face_match']['status'] ?? null; // Approved/Rejected/In Review
$passed = is_numeric($faceScore) && $faceScore >= $minFaceScore &&
!(is_string($faceStatus) && stripos($faceStatus, 'rejected') !== false);
return [
'success' => $passed,
'stage' => 'face_match',
'decision_threshold' => $minFaceScore,
'liveness' => [
'score' => $liveScore,
'status' => $liveStatus,
],
'face_match' => [
'score' => $faceScore,
'status' => $faceStatus,
'warnings' => $matchResp['face_match']['warnings'] ?? [],
],
'raw' => [
'liveness' => $liveResp,
'face_match' => $matchResp,
],
];
}
/* ---------- Helpers ---------- */
public function diditpostjson(string $url, string $apiKey, array $payload): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'x-api-key: ' . $apiKey, // Auth Didit
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_SLASHES),
CURLOPT_TIMEOUT => 60,
]);
$raw = curl_exec($ch);
$err = curl_error($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($err) {
throw new RuntimeException("Erreur cURL: $err");
}
if ($status < 200 || $status >= 300) {
throw new RuntimeException("HTTP $status: $raw");
}
$json = json_decode($raw, true);
if (!is_array($json)) {
throw new RuntimeException("JSON invalide: $raw");
}
return $json;
}
/**
* Construit le payload attendu:
* - si $prefix='image' (liveness), retourne ['image' | 'image_base64' => ...]
* - sinon pour Face Match: ['{prefix}_image' | '{prefix}_image_base64' => ...]
*/
public function buildImagePayload(string $val, string $prefix, bool $forMatch=false): array {
// URL ?
if (preg_match('~^https?://~i', $val)) {
$key = $forMatch ? "{$prefix}_image" : 'image';
return [$key => $val];
}
// Fichier local ?
if (is_file($val)) {
$bin = file_get_contents($val);
if ($bin === false) {
throw new RuntimeException("Lecture impossible: $val");
}
$key = $forMatch ? "{$prefix}_image_base64" : 'image_base64';
return [$key => base64_encode($bin)];
}
// Sinon, assume base64 “nu”
if (preg_match('~^[A-Za-z0-9+/=\r\n]+$~', $val)) {
$key = $forMatch ? "{$prefix}_image_base64" : 'image_base64';
return [$key => $val];
}
throw new InvalidArgumentException("Image non reconnue (URL, fichier ou base64 attendu): $val");
}
public function tester()
{
$apiKey = "lL18NHzgOta3_uKXYKcIG2s5a_Rys9Vq49JrDPVtESc";
$userImagePath = "/var/www/html/production/Temp/mbadan.jpg"; // photo prise en temps réel
$referenceImagePath = "/var/www/html/production/Temp/mbadan.jpg"; // photo d'identité ou d'enregistrement
// Vérification que les fichiers existent
if (!file_exists($userImagePath) || !file_exists($referenceImagePath))
{
die("Erreur : l'un des fichiers images n'existe pas.\n");
}
/*
$API_KEY = getenv('DIDIT_API_KEY'); // récupérée dans le Business Console
$WORKFLOW = getenv('DIDIT_BIO_WORKFLOW_ID'); // workflow "Biometric Authentication"
$CALLBACK = getenv('DIDIT_WEBHOOK_URL'); // votre endpoint webhook
*/
$API_KEY = "lL18NHzgOta3_uKXYKcIG2s5a_Rys9Vq49JrDPVtESc";
$WORKFLOW = ""; // workflow "Biometric Authentication"
$CALLBACK = ""; // votre endpoint webhook
// 1) Charger et encoder en Base64 le portrait de référence (JPG/PNG)
/*
$portraitPath = __DIR__ . '/portrait_reference.jpg';
*/
$portraitPath = "/var/www/html/production/Temp/mbadan.jpg";
$portraitB64 = base64_encode(file_get_contents($portraitPath));
var_dump($portraitB64);
exit();
// 2) Construire la charge utile pour créer la session
$payload = [
"workflow_id" => $WORKFLOW,
"vendor_data" => "user-123", // votre identifiant utilisateur
"callback" => $CALLBACK,
"metadata" => ["reason" => "login"], // champ libre optionnel
"portrait_image"=> $portraitB64 // <- clé pour activer Face Match 1:1
];
$ch = curl_init('https://verification.didit.me/v2/session/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'accept: application/json',
'content-type: application/json',
'x-api-key: ' . $API_KEY
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException('Erreur cURL: ' . curl_error($ch));
}
$code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($code < 200 || $code >= 300) {
throw new RuntimeException("Echec création session (HTTP $code): $response");
}
$session = json_decode($response, true);
// 🔗 URL à présenter/rediriger à lutilisateur pour prendre le selfie + liveness
echo "Open verification URL: " . $session['url'] . PHP_EOL;
// Conservez ces champs pour la suite
$sessionId = $session['session_id'];
$sessionToken = $session['session_token'];
}
}
function diditverifyandmatch(
string $apiKey,
string $selfie,
string $reference,
float $minLiveScore = 0.80, // ex: 0.80 (=80%) liveness pass
float $minFaceScore = 75.0 // ex: 75/100 face match pass
): array {
// 1) Passive Liveness
$livePayload = buildImagePayload($selfie, 'image'); // 'image' ou 'image_base64'
$liveResp = diditpostjson(
'https://verification.didit.me/v2/passive-liveness/',
$apiKey,
$livePayload
);
$liveScore = $liveResp['liveness']['score'] ?? null; // valeur typique 0..1
$liveStatus = $liveResp['liveness']['status'] ?? null; // e.g. Approved/Rejected/In Review
if (!is_numeric($liveScore)) {
throw new RuntimeException('Réponse Liveness invalide: score manquant');
}
if ($liveScore < $minLiveScore || (is_string($liveStatus) && stripos($liveStatus, 'rejected') !== false)) {
return [
'success' => false,
'stage' => 'liveness',
'reason' => 'fail_threshold',
'details' => [
'score' => $liveScore,
'status' => $liveStatus,
'min_required' => $minLiveScore,
],
];
}
// 2) Face Match 1:1 (selfie validé vs référence)
$matchPayload = buildImagePayload($selfie, 'source', true) +
buildImagePayload($reference, 'target', true);
$matchResp = diditpostjson(
'https://verification.didit.me/v2/face-match/',
$apiKey,
$matchPayload
);
$faceScore = $matchResp['face_match']['score'] ?? null; // 0..100
$faceStatus = $matchResp['face_match']['status'] ?? null; // Approved/Rejected/In Review
$passed = is_numeric($faceScore) && $faceScore >= $minFaceScore &&
!(is_string($faceStatus) && stripos($faceStatus, 'rejected') !== false);
return [
'success' => $passed,
'stage' => 'face_match',
'decision_threshold' => $minFaceScore,
'liveness' => [
'score' => $liveScore,
'status' => $liveStatus,
],
'face_match' => [
'score' => $faceScore,
'status' => $faceStatus,
'warnings' => $matchResp['face_match']['warnings'] ?? [],
],
'raw' => [
'liveness' => $liveResp,
'face_match' => $matchResp,
],
];
}
function diditpostjson(string $url, string $apiKey, array $payload): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'x-api-key: ' . $apiKey, // Auth Didit
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_SLASHES),
CURLOPT_TIMEOUT => 60,
]);
$raw = curl_exec($ch);
$err = curl_error($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($err) {
throw new RuntimeException("Erreur cURL: $err");
}
if ($status < 200 || $status >= 300) {
throw new RuntimeException("HTTP $status: $raw");
}
$json = json_decode($raw, true);
if (!is_array($json)) {
throw new RuntimeException("JSON invalide: $raw");
}
return $json;
}
function buildImagePayload(string $val, string $prefix, bool $forMatch=false): array {
// URL ?
if (preg_match('~^https?://~i', $val)) {
$key = $forMatch ? "{$prefix}_image" : 'image';
return [$key => $val];
}
// Fichier local ?
if (is_file($val)) {
$bin = file_get_contents($val);
if ($bin === false) {
throw new RuntimeException("Lecture impossible: $val");
}
$key = $forMatch ? "{$prefix}_image_base64" : 'image_base64';
return [$key => base64_encode($bin)];
}
// Sinon, assume base64 “nu”
if (preg_match('~^[A-Za-z0-9+/=\r\n]+$~', $val)) {
$key = $forMatch ? "{$prefix}_image_base64" : 'image_base64';
return [$key => $val];
}
throw new InvalidArgumentException("Image non reconnue (URL, fichier ou base64 attendu): $val");
}