前言区分
独立h5: 数字、 眨眼
pc h5 : 眨眼
app: 光线、 数字、 动作
普通H5: 数字、 动作、 静默
微信H5: 数字、 光线、 光线 数字
小程序: 数字、 光线、 光线 数字
API:活体人脸比对、活体人脸核身: 数字、 动作、 静默
一、准备工作
(1)开通腾讯云 https://cloud.tencent.com/
(2)腾讯云控制台开通人脸核身权限 https://console.cloud.tencent.com/faceid/access
(3)控制台设置秘钥 https://console.cloud.tencent.com/cam/capi
温馨提示:
注册腾讯云账号且实名认证: https://cloud.tencent.com/
注意:子账号与子账号, 主账号与主账号之间创建的 `ruleid` 及秘钥不互通, 不可互相查看, 不可互相调用, 简单来说就是 A 账号创建的 `ruleid` 只能由 A 账号的秘钥来调用, 常见问题表现于 `ruleid `不存在, `ruleid is not exist`**
计费会统一计算在主账号, 主账号统一结算, 调用量可以用子账号区分
`API `密钥是构建腾讯云 `API `请求的重要凭证,您的 `API `密钥代表您的账号身份和所拥有的权限,等同于您的登录密码,请勿通过任何方式(如 `GitHub`)上传或者分享您的密钥信息,一旦泄露至外部渠道,可能造成您的云上资产重大损失
二、公众号流程准备
公众平台:https://mp.weixin.qq.com/ (仅支持认证过的公众号,订阅号不支持,当前项目以订阅号方式申请测试公众号进行请求)
注册后,进入平台后台->开发者工具
生成测试公众号菜单
获取access_token,生成菜单需要access_token入参,access_token有效期2小时
生成菜单
代码语言:javascript复制#菜单Json数据
{
"button": [
{
"type": "view",
"name": "人脸核身",
"url": "http://xxxxx" #说明:你的入口地址
}
]
}
具体效果
三、普通 H5 接入流程准备工作
四、入口文件发起人脸核身请求
注意:人脸核身鉴权是收费的,此代码未做缓存,发起一次后不管是否继续鉴权,都会计一次调用费用,请谨慎使用
计费规则:https://cloud.tencent.com/document/product/1007/31005
PHP入口执行文件
(1)V3自主鉴权方式获取实名核身鉴权(DetectAuth)中用于发起核身流程的URL,仅微信H5场景使用。
(2)获取结构,URL执行跳转,跳转到相应H5执行
(3)参考文档:https://cloud.tencent.com/document/api/1007/31816
代码语言:javascript复制{
"Response": {
"BizToken": "CE661F1A-0F1E-45BD-BE13-34C05CEA7681",
"Url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx2cca36a86d5035ae&redirect_uri=http://open.faceid.qq.com/v1/api/getCode?bizRedirect=http%3A%2F%2Ffaceid.qq.com%2Fapi%2Fauth%2FgetOpenidAndSaveToken%3Ftoken%3DCE661F1A-0F1E-45BD-BE13-34C05CEA7681&response_type=code&scope=snsapi_base&state=&component_appid=wx9802ee81e68d6dee#wechat_redirect",
"RequestId": "f904f4cf-75db-4f8f-a5ec-dc4f942c7f7a"
}
}
代码语言:javascript复制<?php
class Face
{
const SecretId = "请填入秘钥";
const SecretKey = "请填写秘钥";
const Url = "https://faceid.tencentcloudapi.com";
//算法
const Algo = "sha256";
//规范请求串
const HTTPRequestMethod = "POST";
const CanonicalURI = "/";
const CanonicalQueryString = "";
const CanonicalHeaders = "content-type:application/json; charset=utf-8nhost:faceid.tencentcloudapi.comn";
const SignedHeaders = "content-type;host";//参与签名的头部信息
//签名字符串
const Algorithm = "TC3-HMAC-SHA256";
const Service = "faceid";
const Stop = "tc3_request";
/**
* 实名核身鉴权
*/
public function getDetectAuth()
{
$param = [
'RuleId' => "1",//用于细分客户使用场景,申请开通服务后,可以在腾讯云慧眼人脸核身控制台(https://console.cloud.tencent.com/faceid) 自助接入里面创建,审核通过后即可调用
];
return self::getCommonPostRequest("DetectAuth", $param);
}
/**
* 鉴权
* @param string $action 方法
* @param array $param 参数
* @param string $version 版本号
* @return array
*/
private static function getCommonPostRequest($action, array $param = [], $version = "2018-03-01")
{
//时间戳
$timeStamp = time();
//$timeStamp = 1586333773;
//参数转化Json
$paramJson = json_encode($param);
//规范请求串
$hashedRequestPayload = self::HashEncryption($paramJson);
$canonicalRequest = self::HTTPRequestMethod . "n" .
self::CanonicalURI . "n" .
self::CanonicalQueryString . "n" .
self::CanonicalHeaders . "n" .
self::SignedHeaders . "n" .
$hashedRequestPayload;
//签名字符串
$date = gmdate("Y-m-d", $timeStamp);//UTC 0时区的值
$credentialScope = $date . "/" . self::Service . "/" . self::Stop;
$hashedCanonicalRequest = self::HashEncryption($canonicalRequest);
$stringToSign = self::Algorithm . "n" .
$timeStamp . "n" .
$credentialScope . "n" .
$hashedCanonicalRequest;
//计算签名
$secretDate = self::HashHmacSha256Encryption($date, 'TC3' . self::SecretKey);
$secretService = self::HashHmacSha256Encryption(self::Service, $secretDate);
$secretSigning = self::HashHmacSha256Encryption(self::Stop, $secretService);
//签名
$signature = self::HashHmacSha256Encryption($stringToSign, $secretSigning, false);
echo $signature . " n";
$authorization = self::Algorithm . ' ' .
'Credential=' . self::SecretId . '/' . $credentialScope . ', ' .
'SignedHeaders=' . self::SignedHeaders . ', ' .
'Signature=' . $signature;
//Header头部
$headers = [
"Authorization: $authorization",
"Host: faceid.tencentcloudapi.com",
"Content-Type: application/json; charset=utf-8",
"X-TC-Action: $action",
"X-TC-Version: $version",
"X-TC-Timestamp: $timeStamp",
"X-TC-Region: ap-beijing"
];
//请求
$response = self::get_curl_request(self::Url, $paramJson, self::HTTPRequestMethod, $headers);
//解析
if (!$response) {
return ['code' => 0, 'codeError' => '1002', 'msg' => 'Interface request failed'];
}
$response = json_decode($response, true);
if (!isset($response['Response'])) {
return ['code' => 0, 'codeError' => '1003', 'msg' => 'Response error'];
}
if (isset($response['Response']['Error'])) {
return [
'code' => 0
, 'codeError' => $response['Response']['Error']['Code']
, 'msg' => $response['Response']['Error']['Message']
, 'RequestId' => $response['Response']['RequestId']
];
} else {
return ['code' => 1, 'msg' => 'ok', 'data' => $response['Response']];
}
}
private static function HashEncryption($sign)
{
return strtolower(hash(self::Algo, $sign));
}
private static function HashHmacSha256Encryption($sign, $key, $flag = true)
{
return hash_hmac(self::Algo, $sign, $key, $flag);
}
/**
* @param $url
* @param array $param
* @param string $mothod
* @param array $headers
* @param int $return_status
* @param int $flag
* @return array|bool|string
*/
public static function get_curl_request($url, $param = [], $mothod = 'POST', $headers = [], $return_status = 0, $flag = 0)
{
$ch = curl_init();
if (!$flag) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 6);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (strtolower($mothod) == 'post') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
} else {
$url = $url . "?" . http_build_query($param);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
#curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1"); //代理服务器地址
#curl_setopt($ch, CURLOPT_PROXYPORT, 12639); //代理服务器端口
$ret = curl_exec($ch);
$code = curl_getinfo($ch);
curl_close($ch);
if ($return_status == "1") {
return array($ret, $code);
}
return $ret;
}
}
//执行
$model = new Face();
$response = $model->getDetectAuth();
if ($response["code"] == 1) {
//获取到鉴权URL进行跳转
$url = $response["data"]["Url"];
//鉴权并且调用人脸核身
header("Location: {$url}");
} else {
var_dump($response);
}