本文目录导读:

在 PHP 中实现生物认证(指纹、人脸、虹膜等),PHP 本身无法直接读取生物特征数据,需要依赖前端设备采集 + 后端服务验证的架构,以下是完整的实现方案:
整体架构(必读)
[生物识别设备/手机] --> [前端采集(JS/SDK)] --> [后端PHP API] --> [数据库/认证服务]
- 采集端:指纹仪、手机Face ID、摄像头(通过设备SDK或Web API)
- 传输层:HTTPS + JSON(常见为Token或特征码)
- 验证端:PHP 调用第三方服务或比对数据库中的模板
主要实现方案
方案1:WebAuthn(推荐,标准做法)
适用于指纹/人脸/Windows Hello,使用浏览器原生API,无需安装额外插件。
// 1. 服务端生成认证挑战(注册阶段)
public function generateRegistrationChallenge($userId) {
$challenge = base64_encode(random_bytes(32));
// 保存挑战到session或缓存,有效期5分钟
$_SESSION['webauthn_challenge'] = $challenge;
$options = [
'challenge' => $challenge,
'rp' => ['name' => 'MyApp'],
'user' => [
'id' => hash('sha256', $userId),
'name' => $userId,
],
'pubKeyCredParams' => [
['alg' => -7, 'type' => 'public-key'], // ES256
],
'authenticatorSelection' => [
'authenticatorAttachment' => 'platform', // 平台内置(指纹/人脸)
'userVerification' => 'required'
],
'timeout' => 60000
];
return json_encode($options);
}
// 2. 验证注册响应(处理前端返回的凭证)
public function verifyRegistration($credential) {
// 使用 web-auth/webauthn-lib 库
$publicKeyCredential = $this->deserialize($credential);
$publicKeyCredentialSource = $this->publicKeyCredentialLoader->load(
$publicKeyCredential
);
$authenticatorAssertionResponseValidator->check(
$publicKeyCredentialSource,
$publicKeyCredential,
$this->getChallenge(),
$this->getCredentialRepository()
);
// 保存凭证到数据库
$this->credentialRepository->saveCredentialSource(
$publicKeyCredentialSource
);
return ['success' => true, 'credentialId' => $publicKeyCredentialSource->publicKeyCredentialId];
}
// 3. 登录验证
public function verifyLogin($credential, $challenge) {
$publicKeyCredentialSource = $this->credentialRepository->findOneByCredentialId(
$credential['id']
);
$this->authenticatorAssertionResponseValidator->check(
$publicKeyCredentialSource,
$credential,
$challenge,
$this->credentialRepository
);
// 认证成功,登录用户
$_SESSION['user'] = $publicKeyCredentialSource->userHandle;
return ['success' => true];
}
前端配合(JavaScript):
// 注册流程
async function register() {
const options = await fetch('/api/webauthn/register/challenge')
.then(r => r.json());
const credential = await navigator.credentials.create({
publicKey: options
});
// 发送到后端验证
await fetch('/api/webauthn/register/verify', {
method: 'POST',
body: JSON.stringify(credential)
});
}
推荐库:
web-auth/webauthn-lib(PHP 7.1+)jawhar/webauthn(轻量级)
方案2:指纹仪(通过硬件SDK)
适用于办公室/考勤场景,使用USB指纹仪(如中控智慧、汇顶等):
// 调用设备SDK的CLI工具或API(以中控为例)
public function verifyFingerprint($template) {
// 调用SDK命令(伪代码)
$command = 'fingerprint_verify --template="' . $template . '"';
$result = shell_exec($command);
return json_decode($result, true);
}
// 或通过DLL/共享库调用(使用FFI)
class FingerprintScanner {
private $ffi;
public function __construct() {
if (extension_loaded('ffi')) {
$this->ffi = FFI::cdef(
"int verify_fingerprint(unsigned char *template, int len);",
"libfingerprint.so"
);
}
}
public function match($template) {
return $this->ffi->verify_fingerprint($template, strlen($template));
}
}
关键点:
- 需要安装设备厂商SDK(C/C++库)
- PHP通过
exec()或FFI调用SDK - 指纹模板(二进制)存储在数据库,比对在设备端完成
方案3:人脸识别(调用云服务API)
使用 阿里云/腾讯云/百度AI 的人脸识别服务:
// 以百度AI为例
public function faceVerify($faceImage, $userId) {
$client = new AipFace('你的API_KEY', '你的SECRET_KEY');
// 人脸比对
$result = $client->match([
[
'image' => base64_encode(file_get_contents($faceImage)),
'image_type' => 'BASE64',
],
[
'image' => $this->getUserFaceTemplate($userId), // 数据库中的人脸模板
'image_type' => 'FACE_TOKEN',
]
]);
if ($result['result']['score'] > 80) { // 阈值
return ['authenticated' => true, 'score' => $result['result']['score']];
}
return ['authenticated' => false];
}
方案4:移动端生物认证(原生App + API)
适用于iOS/Android App:
// 后端接收设备验证结果(App内完成验证)
public function verifyMobileBioAuth($deviceToken, $authTicket) {
// 验证设备返回的认证票据
$validation = $this->validateDeviceTicket($deviceToken, $authTicket);
if ($validation['valid']) {
$_SESSION['user'] = $validation['userId'];
return ['success' => true];
}
return ['success' => false, 'error' => '认证失败'];
}
App端流程:
// iOS使用LocalAuthentication
let context = LAContext()
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "验证指纹") { success, error in
if success {
// 生成一次性票据发送给后端
sendTicketToServer()
}
}
安全最佳实践
| 要点 | 实现方式 |
|---|---|
| 数据传输 | 使用HTTPS/WSS加密通道 |
| 模板存储 | 生物特征模板不存储原始数据,存哈希或Token |
| 防重放 | 每次认证生成随机Challenge(一次性) |
| 防篡改 | 签名验证(JWT或HMAC) |
| 阈值控制 | 根据安全等级调整匹配阈值(如人脸识别score>80) |
| 失败锁定 | 连续失败N次锁定账户 |
完整示例:使用 web-auth/webauthn-lib
安装:
composer require web-auth/webauthn-lib
核心代码:
use Webauthn\PublicKeyCredentialCreationOptions;
use Webauthn\PublicKeyCredentialRequestOptions;
class AuthController {
private $publicKeyCredentialSourceRepository;
public function registerStart() {
$userEntity = new PublicKeyCredentialUserEntity(
$_POST['username'],
random_bytes(32),
$_POST['displayName']
);
$options = $this->creationOptionsFactory->create($userEntity);
$_SESSION['webauthn_user'] = $userEntity;
$_SESSION['webauthn_challenge'] = $options->getChallenge();
return new JsonResponse($options);
}
public function registerComplete() {
$request = $this->request->getContent();
$credential = $this->publicKeyCredentialLoader->load($request);
$this->authenticatorAttestationResponseValidator->check(
$credential,
$_SESSION['webauthn_challenge'],
$_SESSION['webauthn_user']
);
// 保存凭证
$this->repository->saveCredentialSource(
$credential->getPublicKeyCredentialSource()
);
return "注册成功";
}
}
总结建议
- Web项目:优先使用 WebAuthn(标准、跨平台、无需额外硬件)
- 硬件定制:使用 指纹仪SDK,PHP作为服务端协调
- 复杂场景:对接云服务API(阿里云、百度AI)
- 移动端:App内调用系统生物认证,后端仅验证结果
关键提示:生物特征的采集必须在设备端完成,PHP端只做逻辑验证和用户关联,切勿在后端处理原始生物特征数据(涉及隐私与合规问题)。