Files
hm-server/pkg/captcha/aliyun.go
2026-02-28 12:29:30 +08:00

82 lines
2.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package captcha
import (
"context"
"net/http"
"os"
"strings"
"tydata-server/common/xerr"
captcha20230305 "github.com/alibabacloud-go/captcha-20230305/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea"
"github.com/pkg/errors"
)
// contextKey 用于在 context 中存储 *http.Request供 VerifyWithRequest 判断微信等环境
type contextKey struct{}
// HTTPRequestContextKey 为 context 中 http.Request 的 keyhandler 可将 r 注入后传入 logic
var HTTPRequestContextKey = &contextKey{}
// isWeChatClient 根据 User-Agent 判断是否为微信内置浏览器/小程序环境(此类环境可不传 captchaVerifyParam默认通过
func isWeChatClient(r *http.Request) bool {
if r == nil {
return false
}
ua := strings.ToLower(r.Header.Get("User-Agent"))
return strings.Contains(ua, "micromessenger") || strings.Contains(ua, "miniprogram")
}
type Config struct {
AccessKeyID string
AccessKeySecret string
EndpointURL string
SceneID string
}
// VerifyWithRequest 在 Verify 基础上支持按请求头判断:微信/小程序环境下可不传 captchaVerifyParam默认通过。
// 若 ctx 中带有 HTTPRequestContextKey 的 *http.Request且 User-Agent 为微信环境,则不再校验 captchaVerifyParam。
func VerifyWithRequest(cfg Config, captchaVerifyParam string, ctx context.Context) error {
if ctx != nil {
if req, ok := ctx.Value(HTTPRequestContextKey).(*http.Request); ok && isWeChatClient(req) {
return nil
}
}
return Verify(cfg, captchaVerifyParam)
}
func Verify(cfg Config, captchaVerifyParam string) error {
if os.Getenv("ENV") == "development" {
return nil
}
if captchaVerifyParam == "" {
return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败captchaVerifyParam 不能为空"), "empty captchaVerifyParam")
}
clientCfg := &openapi.Config{
AccessKeyId: tea.String(cfg.AccessKeyID),
AccessKeySecret: tea.String(cfg.AccessKeySecret),
}
clientCfg.Endpoint = tea.String(cfg.EndpointURL)
client, err := captcha20230305.NewClient(clientCfg)
if err != nil {
return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败"), "new client error: %+v", err)
}
req := &captcha20230305.VerifyIntelligentCaptchaRequest{
SceneId: tea.String(cfg.SceneID),
CaptchaVerifyParam: tea.String(captchaVerifyParam),
}
resp, err := client.VerifyIntelligentCaptcha(req)
if err != nil {
return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败"), "verify request error: %+v", err)
}
if tea.BoolValue(resp.Body.Result.VerifyResult) {
return nil
}
return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败"), "verify result false")
}