qnc-server-tob/pkg/core/aliyun/cloudauth/client.go

179 lines
5.1 KiB
Go
Raw Normal View History

2025-05-24 14:26:20 +08:00
package cloudauth
import (
"encoding/json"
"fmt"
cloudauth "github.com/alibabacloud-go/cloudauth-20190307/v4/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/aliyun/credentials-go/credentials"
"github.com/zeromicro/go-zero/core/logx"
)
type CloudAuthClient struct {
Client *cloudauth.Client
Config *CloudAuthConfig
}
type CloudAuthConfig struct {
AccessKeyId string
AccessKeySecret string
Endpoint string
SceneId int64
ReturnUrl string
}
type InitFaceVerifyResp struct {
CertifyId string
CertifyUrl string
}
type DescribeFaceVerifyResp struct {
Passed bool
}
// InitFaceVerifyRequest 封装初始化人脸认证所需参数
type InitFaceVerifyParam struct {
OuterOrderNo string
CertName string
CertNo string
MetaInfo string
}
// NewCloudAuthClient 创建阿里云人脸认证客户端
func NewCloudAuthClient(cloudAuthconfig CloudAuthConfig) (*CloudAuthClient, error) {
// 使用AK 初始化Credentials Client。
credentialsConfig := new(credentials.Config).
// 凭证类型。
SetType("access_key").
// 设置为AccessKey ID值。
SetAccessKeyId(cloudAuthconfig.AccessKeyId).
// 设置为AccessKey Secret值。
SetAccessKeySecret(cloudAuthconfig.AccessKeySecret)
credentialClient, _err := credentials.NewCredential(credentialsConfig)
if _err != nil {
panic(_err)
}
ecsConfig := &openapi.Config{}
// 配置云产品服务接入地址endpoint
ecsConfig.Endpoint = tea.String(cloudAuthconfig.Endpoint)
// 使用Credentials配置凭证。
ecsConfig.Credential = credentialClient
// 创建客户端
client, err := cloudauth.NewClient(ecsConfig)
if err != nil {
panic(fmt.Sprintf("创建阿里云人脸认证客户端失败: %v", err))
}
return &CloudAuthClient{
Client: client,
Config: &CloudAuthConfig{
AccessKeyId: cloudAuthconfig.AccessKeyId,
AccessKeySecret: cloudAuthconfig.AccessKeySecret,
Endpoint: cloudAuthconfig.Endpoint,
SceneId: cloudAuthconfig.SceneId,
ReturnUrl: cloudAuthconfig.ReturnUrl,
},
}, nil
}
// InitFaceVerify 初始化人脸认证
func (c *CloudAuthClient) InitFaceVerify(param InitFaceVerifyParam) (*InitFaceVerifyResp, error) {
request := &cloudauth.InitFaceVerifyRequest{
SceneId: tea.Int64(c.Config.SceneId),
OuterOrderNo: tea.String(param.OuterOrderNo),
ProductCode: tea.String("ID_PRO"),
Model: tea.String("LIVENESS"),
CertType: tea.String("IDENTITY_CARD"),
CertName: tea.String(param.CertName),
CertNo: tea.String(param.CertNo),
MetaInfo: tea.String(param.MetaInfo),
ReturnUrl: tea.String(c.Config.ReturnUrl),
}
runtime := &util.RuntimeOptions{
ReadTimeout: tea.Int(10000),
ConnectTimeout: tea.Int(5000),
}
response, err := c.Client.InitFaceVerifyWithOptions(request, runtime)
if err != nil {
if sdkErr, ok := err.(*tea.SDKError); ok {
logx.Errorf("认证初始化失败: %s, 建议: %s",
tea.StringValue(sdkErr.Message),
getRecommendFromError(sdkErr))
return nil, fmt.Errorf("认证初始化失败: %s", tea.StringValue(sdkErr.Message))
}
logx.Errorf("认证初始化失败: %v", err)
return nil, fmt.Errorf("认证初始化失败: %v", err)
}
if tea.StringValue(response.Body.Code) != "200" {
logx.Errorf("认证初始化失败: %s", tea.StringValue(response.Body.Message))
return nil, fmt.Errorf("认证初始化失败: %s", tea.StringValue(response.Body.Message))
}
return &InitFaceVerifyResp{
CertifyId: tea.StringValue(response.Body.ResultObject.CertifyId),
CertifyUrl: tea.StringValue(response.Body.ResultObject.CertifyUrl),
}, nil
}
// DescribeFaceVerify 获取认证结果
func (c *CloudAuthClient) DescribeFaceVerify(certifyId string) (*DescribeFaceVerifyResp, error) {
request := &cloudauth.DescribeFaceVerifyRequest{
SceneId: tea.Int64(c.Config.SceneId),
CertifyId: tea.String(certifyId),
}
runtime := &util.RuntimeOptions{
ReadTimeout: tea.Int(10000),
ConnectTimeout: tea.Int(5000),
}
response, err := c.Client.DescribeFaceVerifyWithOptions(request, runtime)
if err != nil {
logx.Errorf("获取认证结果失败: %v", err)
return nil, fmt.Errorf("获取认证结果失败: %v", err)
}
if tea.StringValue(response.Body.Code) != "200" {
logx.Errorf("获取认证结果失败: %s", tea.StringValue(response.Body.Message))
return nil, fmt.Errorf("获取认证结果失败: %s", tea.StringValue(response.Body.Message))
}
var passed bool
var passedStr = tea.StringValue(response.Body.ResultObject.Passed)
switch passedStr {
case "T":
passed = true
case "F":
passed = false
default:
passed = false
}
return &DescribeFaceVerifyResp{
Passed: passed,
}, nil
}
// 从SDK错误中获取推荐信息
func getRecommendFromError(err *tea.SDKError) string {
if err == nil || err.Data == nil {
return ""
}
var data map[string]interface{}
if err := json.Unmarshal([]byte(tea.StringValue(err.Data)), &data); err != nil {
return ""
}
if recommend, ok := data["Recommend"].(string); ok {
return recommend
}
return ""
}