蛋蛋星球-制度模式
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

80 行
2.3 KiB

  1. package sms
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/hex"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "io/ioutil"
  10. "net/http"
  11. "net/url"
  12. "time"
  13. )
  14. // 验证服务地址
  15. const API_SERVER string = "https://captcha.alicaptcha.com"
  16. // 二次校验接口
  17. const URL = API_SERVER + "/validate" + "?captcha_id="
  18. // 图形校验
  19. func AliyunCheckCaptcha(CaptchaId, CaptchaKey string, datas map[string]string) error {
  20. lotNumber := datas["lot_number"]
  21. captchaOutput := datas["captcha_output"]
  22. passToken := datas["pass_token"]
  23. genTime := datas["gen_time"]
  24. // 生成签名
  25. // 生成签名使用标准的hmac算法,使用用户当前完成验证的流水号lot_number作为原始消息message,使用客户验证私钥作为key
  26. // 采用sha256散列算法将message和key进行单向散列生成最终的 “sign_token” 签名
  27. signToken := hmac_encode(CaptchaKey, lotNumber)
  28. // 向验证服务转发前端数据 + “sign_token” 签名
  29. formData := make(url.Values)
  30. formData["lot_number"] = []string{lotNumber}
  31. formData["captcha_output"] = []string{captchaOutput}
  32. formData["pass_token"] = []string{passToken}
  33. formData["gen_time"] = []string{genTime}
  34. formData["sign_token"] = []string{signToken}
  35. // 发起post请求
  36. // 设置5s超时
  37. cli := http.Client{Timeout: time.Second * 5}
  38. resp, err := cli.PostForm(URL+CaptchaId, formData)
  39. if err != nil || resp.StatusCode != 200 {
  40. // 当请求发生异常时,应放行通过,以免阻塞业务
  41. fmt.Println("服务接口异常: ")
  42. fmt.Println(err)
  43. return errors.New("验证失败")
  44. }
  45. resJson, _ := ioutil.ReadAll(resp.Body)
  46. var resMap map[string]interface{}
  47. // 根据验证服务返回的用户验证状态, 网站主进行自己的业务逻辑
  48. // 响应json数据如:{"result": "success", "reason": "", "captcha_args": {}}
  49. if err = json.Unmarshal(resJson, &resMap); err != nil {
  50. fmt.Println("Json数据解析错误")
  51. return errors.New("验证失败")
  52. }
  53. result := resMap["result"]
  54. if result == "success" {
  55. fmt.Println("验证通过")
  56. return nil
  57. } else {
  58. reason := resMap["reason"]
  59. fmt.Print("验证失败: ")
  60. fmt.Print(reason)
  61. return errors.New("验证失败")
  62. }
  63. }
  64. // hmac-sha256 加密: CAPTCHA_KEY,lot_number
  65. func hmac_encode(key string, data string) string {
  66. mac := hmac.New(sha256.New, []byte(key))
  67. mac.Write([]byte(data))
  68. return hex.EncodeToString(mac.Sum(nil))
  69. }