想不到以前的草稿还能拿出来写。
最近将代码重构了,看情况回头修以前文章的bug(机率不大
reCAPTCHA是google推出的我不是机器人服务,可以帮忙过滤一些机器人的流量,这边以V3版本为例,google会根据使用者的一些行为判断使用者有多像机器人,而不需要让使用者花时间去点图形。
先到reCAPTCHA官网申请帐号,在网域的地方输入自己的网域,有趣的是,如果想在本地测试,输入127.0.0.1也可以使用。
之後会得到两组金钥,一组是用於前端,另一组则是要放在自己server上不能随意公开的
根据官方文件的描述,可以直接将reCAPTCHA绑订在一个按钮上,但这方法较没有弹性,所以使用下面一种方法。
假设我们希望发出登陆请求的使用者不是机器人,打开sign.js,将登入的地方改写
let reCAPTCHA_token = "6LcCuJwdAAAAAI2ITaq_01Xobie7X2FK9hTLuEvP";
$("#SignForm").submit(function(e) {
let url = $(this).attr('action');
let username = $("#InputUserName").val();
let password = $("#InputPassword").val();
let data = new FormData();
data.append('username', username);
data.append('password', password);
grecaptcha.ready(function() {
grecaptcha.execute(reCAPTCHA_token, {action: 'submit'}).then(function(token) {
// Add your logic to submit to your backend server here.
data.append('response', token);
$.ajax({
method: "POST",
url: url,
data: data,
processData: false,
contentType: false,
xhrFields: {
withCredentials: true
},
success: function(data){
console.log(data)
SetUserCookie(data.user)
window.location.reload();
},
error: function(jqXHR, textStatus, errorThrown){
console.log(jqXHR)
console.log(textStatus)
console.log(errorThrown)
$("#AlertWrongParam").show();
}
});
});
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});
解释:
当按下送出表单後,会先把请求发给google检查是否是机器人,google会回应一组token,接着将这组token跟使用者的资料送到後台处理
後台要将这笔token送给google来确定这位使用者的分数,这过程还需要我们的另一组金钥来认证
在middleware/auth.go补上
func CheckRobot() gin.HandlerFunc {
return func(c *gin.Context) {
serve.CheckRobot(c)
if c.IsAborted() {
return
}
c.Next()
}
}
之後可以在router package选择想要检查是否是机器人的路径上接上这个middleware
在serve/auth.go补上
// check request is by robot
func CheckRobot(c *gin.Context) {
resp, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify",
url.Values{
"secret": {"your key"},
"response": {c.PostForm("response")},
"remoteip": {c.ClientIP()},
},
)
}
发送请求给google,接着处理google的回应,取得google判断的分数,在CheckRobot内补上
if err != nil {
log.Warn(c, apperr.ErrPermissionDenied, err, "Sorry, something error", "error in sent post request to reCAPTCHA")
c.Abort()
return
}
var res map[string]interface{}
json.NewDecoder(resp.Body).Decode(&res)
// parse google response
if val, ok := res["success"].(bool); !ok {
err := errors.New("wrong error type")
log.Error(c, apperr.ErrSystemFail, err, 0, "Sorry, something error", "assert wrong type")
c.Abort()
return
} else if !val {
err := errors.New("wrong argument")
log.Warn(c, apperr.ErrWrongArgument, err, "Sorry, something error", "wrong response token")
c.Abort()
return
}
有了分数就能以此来决定怎麽做了,这边的处理逻辑是直接无视掉太像机器人(分数小於自订的score值)的请求,在CheckRobot内补上。
// compare score
score, err := strconv.ParseFloat(setting.Servers["main"].ReCAPTCHA["AcceptScore"], 64)
if err != nil {
log.Warn(c, apperr.ErrWrongArgument, err, "Sorry, something error", "parse config string to float fail")
c.Abort()
return
}
if val, ok := res["score"].(float64); !ok {
err = errors.New("wrong error type")
log.Error(c, apperr.ErrSystemFail, err, 0, "Sorry, something error", "assert wrong type")
c.Abort()
return
} else if val < score {
err := errors.New("robot denied")
log.Warn(c, apperr.ErrWrongArgument, err, "Sorry, we don't accept robot", "robot denied")
c.Abort()
return
}
>>: 因边界网关协议 ( BGP) 路由配置错误导致 DNS 故障而遭受服务中断,防止此事件的最佳对策-对配置更改实施两人控制
前几篇重点放在 JUCE GUI 相关工具,接下来换个口味,介绍几个 JUCE 提供的好用组件。首先...
前言: 本来要睡了但感觉今天过得太废了所以惩罚自己再打一篇,明天要去自己最喜欢的导演开设的酒吧参加活...
新版本的 Windows 作业系统,但是不少用户还是喜欢用经典的 Windows 7/8 版本。我们...
前言 历经千辛万苦,那我们在train Model 时,总会发现有时效果不好,可能Training ...
Hello rookie! 在经过昨天安装完环境後,相信大家已经迫不及待要写第一支程序了吧。 相信大...