PHP 怎么生物认证

wen PHP项目 2

本文目录导读:

PHP 怎么生物认证

  1. 整体架构(必读)
  2. 主要实现方案
  3. 安全最佳实践
  4. 完整示例:使用 web-auth/webauthn-lib
  5. 总结建议

在 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)
    });
}

推荐库


方案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 "注册成功";
    }
}

总结建议

  1. Web项目:优先使用 WebAuthn(标准、跨平台、无需额外硬件)
  2. 硬件定制:使用 指纹仪SDK,PHP作为服务端协调
  3. 复杂场景:对接云服务API(阿里云、百度AI)
  4. 移动端:App内调用系统生物认证,后端仅验证结果

关键提示:生物特征的采集必须在设备端完成,PHP端只做逻辑验证和用户关联,切勿在后端处理原始生物特征数据(涉及隐私与合规问题)。

抱歉,评论功能暂时关闭!