我是如何使用recaptcha v3来防止机器人登陆的

起因

  • 最近公司的一个登陆业务受到恶意攻击,攻击者不停地请求登陆接口,用不同的用户名,尝试登陆,导致后端的redis数据增长的很快
  • 为了解决这个问题,我先行尝试,引入谷歌的recaptcha v3

recaptchaV3的优势

  • 无需用户输入验证码,即使是变种的拼图快,点文字,选图片等,这样可以改善用户体验

机制

  • 通过recaptcha v3,接口会给出风险评分,从0.1到1,网站管理员将能够决定后端对这些分数做出对应的处理。

流程图

  • [
    我是如何使用recaptcha v3来防止机器人登陆的_第1张图片
    image

    ]

着手解决

  • 引入recaptcha v3的方式不复杂,查看官方的文档即可

申请密钥

  • 打开网页 https://www.google.com/recaptcha/admin ,登录谷歌账号,申请开通这个业务
  • 在这个过程中,需要输入自己网站的hostname
  • 申请完成后,会提供2个秘钥

前端引入

  • 按照文档所说,在前端页面引入一个js文件,并加载,结合实际网站的需求,可能需要略做一些调整,我的代码如下:

    
  • 当用户点击登录按钮之后,会将js生成的token作为post数据传入后端
  • 后端再做处理

后端处理

  • 后端的部分可以参考官方文档
  • 将前端传过来的参数,进行一些组织,发送post请求到谷歌服务端
  • 谷歌服务端返回响应的内容,我们后端再根据响应的内容判断这个登陆请求是否是机器人,主要根据其中的score字段,它的值为0-1之间,score为0,表示用户很可能是机器人,如果为0.91,则是非机器人请求。
  • 上核心代码:
// 向谷歌服务端发送请求
public function resolveRecaptchaV3(array $params)
    {
        $options = [
            'secret'   => '',// required. The shared key between your site and reCAPTCHA.
            'response' => '',// required.  The user response token provided by the reCAPTCHA client-side integration on your site.
            'remoteip' => '',// optional. The user's IP address.
        ];
        $options = array_merge($options, $params);
        $result = HttpRequestService::curlHttp([
            'url'      => 'https://www.google.com/recaptcha/api/siteverify',// string 请求的url
            'method'   => 'post',// string 请求类型
            'postData' => [
                'secret'   => $options['secret'],
                'response' => $options['response'],
                'remoteip' => $options['remoteip'],
            ],// array 数组类型
            'bodyType' => 1,
        ]);
        if ($result['status'] != 1) {
            throw new \Exception("请求谷歌机器人验证异常:[{$result['msg']}]", 400);
        }
        $responseJson = $result['data'];
        $responsArr = json_decode($responseJson, true);
        if ($responsArr['success'] !== true) {
            throw new \Exception(implode("\n", $responsArr['error-codes']), 401);
        }

        return ['status'=>1, 'msg'=>'验证完成!','data'=>$responsArr,];
    }
  • 根据score判断是否是机器人,可以根据实际情况做调整
  • 其中http请求的方法定义见github代码
public function checkIsBot(array $params)
    {
        $options = [
            'score' => 0,
        ];
        $options = array_merge($options, $params);
        if ($options['score'] < 0.2) {
            return ['status'=>3,'msg'=>'您是机器人!'];
        } else if ($options['score']>=0.2 && $options['score'] < 0.6) {
            return ['status'=>2,'msg'=>'您可能是机器人!'];
        }else{
            return ['status'=>1,'msg'=>'机器人验证通过!'];
        }
    }
  • 登录的post请求中,先请求谷歌服务端,合格后,再继续后续的处理:
public function selfPostLogin(Request $request)
{
    // 人机识别
    $result = $this->resolveReCAPTCHAV3($request);
    // status为1、2的,大概率不是机器人
    if ($result['status'] != 1 && $result['status'] != 2) {
        $validate = Validator::make([],[])->errors()->add('isValid',"您的身份可能是机器人。{$result['msg']}");
        return back()->withErrors($validate);
    }

    return $this->postLogin($request);
}
  • 这段代码中第7行,会在失败时,跳回登录页,并提示错误信息。

结束

  • 好了,以上就是此次引入recaptcha v3的主要过程
  • 有什么问题,欢迎在留言区留言

参考资料

  • https://blog.csdn.net/C_jian/article/details/84191095
  • https://baijiahao.baidu.com/s?id=1616275069549421082&wfr=spider&for=pc

你可能感兴趣的:(我是如何使用recaptcha v3来防止机器人登陆的)