【笔记】CloudflareTurnstile学习笔记

前言

CloudflareTurnstile学习笔记

获取密钥

  • 定义站点名称和域名->创建

  • 复制站点密钥密钥

用于测试的密钥对

站点密钥:1x00000000000000000000AA
密钥:1x0000000000000000000000000000000AA

前端验证

  • 发送请求给Cloudflare获取token
1
2
3
4
5
6
7
8
9
10
11
12
13
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"></script>
<button id="example-container">提交</button>
<script>
turnstile.ready(function () {
turnstile.render('#example-container', {
sitekey: '站点密钥',
callback: function(token) {
console.log(token);
// 发送给后端进行验证
},
});
});
</script>
  • 把从Cloudflare获取token发送请求给后端
request
1
2
3
4
POST http://localhost:8080/api
Content-Type: application/json

{username: "", password: "", token: "从Cloudflare获取的token"}

后端验证

  • 发送请求给Cloudflare验证从前端获取的token
request
1
2
3
4
POST https://challenges.cloudflare.com/turnstile/v0/siteverify
Content-Type: application/json

{secret: "密钥", response: "从前端获取的token"}

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)

type CloudflareTurnstileVerificationResponseEntity struct {
Success bool `json:"success"`
ErrorCodes []string `json:"error-codes"`
ChallengeTS string `json:"challenge_ts"`
Hostname string `json:"hostname"`
Action string `json:"action"`
Cdata string `json:"cdata"`
Messages []string `json:"messages"`
}

func CloudflareTurnstileVerification(token string) (err error, success bool) {

var url = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
var secret = "密钥"

// 请求体参数
var requestPayloadMap map[string]string = map[string]string{
"secret": secret,
"response": token,
}
var requestPayloadString string
if res, err := json.Marshal(requestPayloadMap); err != nil {
return err, success
} else {
requestPayloadString = string(res)
}
// 发起请求获取响应
var responseEntity *http.Response
if res, err := http.Post(url, "application/json", strings.NewReader(requestPayloadString)); err != nil {
return err, success
} else {
responseEntity = res
}
defer responseEntity.Body.Close()
// 将响应体转换为文本
var responseText []byte
if res, err := ioutil.ReadAll(responseEntity.Body); err != nil {
return err, success
} else {
responseText = res
}
// 将JSON格式的响应体文本转换为响应体结构体
var responseObject CloudflareTurnstileVerificationResponseEntity
if err := json.Unmarshal(responseText, &responseObject); err != nil {
return err, success
}
if responseObject.Success == false {
var errorCodeListString strings.Builder
errorCodeListString.WriteString("\nErrorCodes:\n")
for i := 0; i < len(responseObject.ErrorCodes); i++ {
errorCodeListString.WriteString(fmt.Sprintf("%d:%s\n", i, responseObject.ErrorCodes[i]))
}
errorCodeListString.WriteString("\nMessages:\n")
for i := 0; i < len(responseObject.Messages); i++ {
errorCodeListString.WriteString(fmt.Sprintf("%d:%s\n", i, responseObject.Messages[i]))
}
return err, false
}

return err, true
}

完成

参考文献

CloudflareDocs
CloudflareDocs