蛋蛋星球-制度模式
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

81 linhas
2.5 KiB

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