Files
sub2api/backend/internal/repository/aliyun_captcha_verifier.go
T

82 lines
2.6 KiB
Go
Raw Normal View History

package repository
import (
"context"
"errors"
"fmt"
captcha "github.com/alibabacloud-go/captcha-20230305/client"
openapiutil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/dara"
"github.com/alibabacloud-go/tea/tea"
"github.com/Wei-Shaw/sub2api/internal/service"
)
const aliyunCaptchaTimeoutMillis = 10_000
type aliyunCaptchaVerifier struct {
protocol string // "HTTPS";测试注入 "HTTP" 指向 httptest.Server
timeoutMillis int
}
func NewAliyunCaptchaVerifier() service.AliyunCaptchaVerifier {
return &aliyunCaptchaVerifier{
protocol: "HTTPS",
timeoutMillis: aliyunCaptchaTimeoutMillis,
}
}
// VerifyCaptcha 调用阿里云验证码 2.0 VerifyIntelligentCaptcha。
// AK/SK 是可热更的后台设置,每次调用按当前凭证新建 client。
func (v *aliyunCaptchaVerifier) VerifyCaptcha(ctx context.Context, cred service.AliyunCaptchaCredentials, captchaVerifyParam string) (*service.AliyunCaptchaVerifyResult, error) {
client, err := captcha.NewClient(&openapiutil.Config{
AccessKeyId: dara.String(cred.AccessKeyID),
AccessKeySecret: dara.String(cred.AccessKeySecret),
Endpoint: dara.String(cred.Endpoint),
Protocol: dara.String(v.protocol),
ConnectTimeout: dara.Int(v.timeoutMillis),
ReadTimeout: dara.Int(v.timeoutMillis),
})
if err != nil {
return nil, fmt.Errorf("create aliyun captcha client: %w", err)
}
request := &captcha.VerifyIntelligentCaptchaRequest{
CaptchaVerifyParam: dara.String(captchaVerifyParam),
SceneId: dara.String(cred.SceneID),
}
response, err := client.VerifyIntelligentCaptchaWithContext(ctx, request, &dara.RuntimeOptions{})
if err != nil {
return nil, normalizeAliyunCaptchaError(err)
}
result := &service.AliyunCaptchaVerifyResult{}
if body := response.Body; body != nil && body.Result != nil {
result.VerifyResult = dara.BoolValue(body.Result.VerifyResult)
result.VerifyCode = dara.StringValue(body.Result.VerifyCode)
}
return result, nil
}
// normalizeAliyunCaptchaError 把 SDK 的两种错误类型归一化为 service.AliyunCaptchaAPIError
// 其余错误(网络/超时等)原样返回。
func normalizeAliyunCaptchaError(err error) error {
var teaErr *tea.SDKError
if errors.As(err, &teaErr) {
return &service.AliyunCaptchaAPIError{
Code: tea.StringValue(teaErr.Code),
Message: tea.StringValue(teaErr.Message),
}
}
var daraErr *dara.SDKError
if errors.As(err, &daraErr) {
return &service.AliyunCaptchaAPIError{
Code: dara.StringValue(daraErr.Code),
Message: dara.StringValue(daraErr.Message),
}
}
return err
}