将Google reCAPTCHA连接到Vue并验证服务器上的响应


在本文中,我将展示如何将验证码从Google(reCAPTCHA)连接到Vue JS并验证服务器上的响应(我以Laravel / Lumen上的后端为例,但是验证的原理对于所有技术都是相同的)。


前言


我们将使用Invisible reCAPTCHA
这是一个不可见的*验证码,直到系统认为有必要时才需要传递。 站点管理员可以设置阈值级别(安全首选项),系统将在该阈值级别上要求用户进行其他验证。


*-reCAPTCHA图标仍应显示在页面上。



网站上的隐形验证码。


问题/答案


在开始工作之前,我想回答我开始使用Google reCAPTCHA时出现的问题。


问:reCAPTCHA的费用是多少?
答:Google提供的ReCAPTCHA是免费的工具。


问:如果后端已经通过网站上的验证码,为什么我需要在后端再次检查用户的响应?
答:向服务器发出请求时,您将发送如下内容:


POST /register 1.1 HTTP Host: www.example.com { "email:"user@gmail.com", "password": "supersecret", "recaptcha-token":"01ASJASJFZ_AASD3115..." } 

如果您不检查后端的验证码令牌,则僵尸程序可以简单地用请求发送垃圾邮件而不使用此令牌,或将其替换为虚拟令牌。


问:我有反应,该怎么办?
答:React JS很棒。 如果您将其用于网站开发,建议您注意https://github.com/appleboy/react-recaptcha 。 操作原理与Vue的示例非常相似。


开始工作


所以,在我们开始做饭之前,我们需要一个配料表:



步骤#1:获取在您的网站上使用reCAPTCHA的密钥


我们需要在Google网站上获取站点密钥秘密密钥https : //www.google.com/recaptcha/admin#list



您可以在标签字段中写任何东西。


接下来,选择类型-Invisible reCAPTCHA badge


您可以指定将在其上使用验证码的多个域。
例如,我已经指出了yourawesomedomain.comlocalhost


我们接受使用条款并继续前进。



您已获得了两个钥匙,请将它们放在安全的地方。 我们稍后再返回。


步骤2:前端。 安装验证码并将其连接到我们的表格


首先,我们需要将此代码添加到头部:


 <script src="https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit" async defer></script> 

onload属性将告诉我们的组件,验证码已经可以使用了。


接下来,我将显示完成的组件,然后我们将对其进行部分分析:


 <template> <div id="app"> <div class="container my-4"> <div class="row justify-content-center"> <div class="col-md-8"> <h2 class="text-center mb-4"> Sign Up Form with Google reCAPTCHA </h2> <form method="post" @submit.prevent="validate"> <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Enter your e-mail address" required /> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Enter your password" required /> </div> <div class="form-group"> <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> <button type="submit" class="btn btn-primary btn-block"> Sign Up </button> </div> </form> </div> </div> </div> </div> </template> <script> import VueRecaptcha from 'vue-recaptcha' export default { name: 'Register', components: { VueRecaptcha }, data () { return { email: null, password: null, sitekey: ' SITE KEY' } }, methods: { register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) }, validate () { //       // ,   vee validate //       ,   this.$refs.recaptcha.execute() }, onCaptchaExpired () { this.$refs.recaptcha.reset() } } } </script> 

使用VeeValidate验证字段的组件示例
 <template> <div id="app"> <div class="container my-4"> <div class="row justify-content-center"> <div class="col-md-8"> <h2 class="text-center mb-4"> Sign Up Form with Google reCAPTCHA </h2> <form method="post" @submit.prevent="validate"> <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Enter your e-mail address" v-validate.disable="'required|email'" required /> <div v-show="errors.has('email')" class="invalid-feedback d-block" > {{ errors.first('email') }} </div> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Enter your password" v-validate.disable="'required|min:6|max:32'" required /> <div v-show="errors.has('password')" class="invalid-feedback d-block" > {{ errors.first('password') }} </div> </div> <div class="form-group"> <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> <button type="submit" class="btn btn-primary btn-block"> Sign Up </button> </div> </form> </div> </div> </div> </div> </template> <script> import VueRecaptcha from 'vue-recaptcha' export default { name: 'Register', components: { VueRecaptcha }, data () { return { email: null, password: null, sitekey: ' SITE KEY' } }, methods: { register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) }, validate () { const self = this self.$validator.validateAll().then((result) => { if (result) { self.$refs.recaptcha.execute() } }) }, onCaptchaExpired () { this.$refs.recaptcha.reset() } } } </script> 

首先,我们将Vue-Recaptcha导入到我们的组件中:


 import VueRecaptcha from 'vue-recaptcha' ... components: { VueRecaptcha }, 

接下来,我们在data()组件中声明了sitekey属性:


 data () { return { ... sitekey: ' SITE KEY' } }, 

将Vue-Recaptcha组件添加到我们的表单中:


 <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> 

成功完成验证码时将调用register方法,而在验证码到期时将调用过期方法。


onCaptchaExpired方法重新启动验证码:


 onCaptchaExpired () { this.$refs.recaptcha.reset() } 

表单本身上,我们添加@ Submit.prevent =“ validate”事件,该事件在提交表单时触发validate方法。


 validate () { this.$refs.recaptcha.execute() } 

该过程可以描述如下:


  1. 用户输入数据并单击“注册”按钮,将调用validate()函数。
  2. validate()函数将启动验证码,如果用户成功通过验证码,则会调用register方法。

在register方法中,我们获得了recaptchaToken ,它必须与用户输入的数据一起发送到服务器:


 register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) } 

至此,我们与前端的工作完成了。 ReCAPTCHA已成功安装并运行。


PS:如果要在多个组件中使用验证码,最好将sitekey放在.env文件中,并使用process.env进行获取:


 data () { return { ... sitekey: process.env.VUE_APP_RECAPTCHA_TOKEN } }, 

步骤#3:后端验证。 Laravel和Lumen上的验证示例


在服务器上进行响应验证非常简单。 让我们从Laravel示例开始。


1)在config文件夹中,创建具有以下内容的recaptcha.php文件:


 <?php return [ 'enabled' => env('RECAPTCHA_ENABLED', true), 'key' => env('RECAPTCHA_SITE_KEY'), 'secret' => env('RECAPTCHA_SECRET_KEY'), ]; 

2)之后,将变量添加到.env文件:


 RECAPTCHA_ENABLED=FALSE RECAPTCHA_SITE_KEY=_SITE_KEY RECAPTCHA_SECRET_KEY=_SECRET_KEY 

3)安装GuzzleHttp以便能够发送Google API请求:


 composer require guzzlehttp/guzzle 

4)在控制器中,添加checkRecaptcha方法:


 protected function checkRecaptcha($token, $ip) { $response = (new Client)->post('https://www.google.com/recaptcha/api/siteverify', [ 'form_params' => [ 'secret' => config('recaptcha.secret'), 'response' => $token, 'remoteip' => $ip, ], ]); $response = json_decode((string)$response->getBody(), true); return $response['success']; } 

在这种方法中,我们使用POST方法将令牌(从前端收到的令牌)发送到https://www.google.com/recaptcha/api/siteverify


5)在register方法(您的情况下,名称可能有所不同,这是您从前端向其发送POST请求的方法)中添加以下代码:


 if (config('recaptcha.enabled') && !$this->checkRecaptcha($request->recaptcha_token, $request->ip())) { return return response()->json([ 'error' => 'Captcha is invalid.', ], Response::HTTP_BAD_REQUEST); } 

一切准备就绪!


  • 当访问register方法时,我们会收到电子邮件,密码和recaptcha_token。
  • 如果启用了recaptcha(在.env文件中,值RECAPTCHA_ENABLED为TRUE),
    Laravel将发送Google API请求。
  • 如果答案是否定的,我们将返回以下文本错误:验证码无效。
  • 如果是肯定的,则继续用户注册。


代币旅行 视觉呈现。


完整的控制器代码如下所示:


 <?php namespace App\Http\Controllers\Users; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Http\Response; use GuzzleHttp\Client; class UserController extends Controller { protected function checkRecaptcha($token, $ip) { $response = (new Client)->post('https://www.google.com/recaptcha/api/siteverify', [ 'form_params' => [ 'secret' => config('recaptcha.secret'), 'response' => $token, 'remoteip' => $ip, ], ]); $response = json_decode((string)$response->getBody(), true); return $response['success']; } public function register(Request $request) { $request->validate([ 'email' => 'required|string|email|unique:users|max:255', 'password' => 'required|string|max:32|min:6', 'recaptcha_token' => 'string' ]); if (config('recaptcha.enabled') && !$this->checkRecaptcha($request->recaptcha_token, $request->ip())) { return response()->json([ 'error' => 'Captcha is invalid.', ], Response::HTTP_BAD_REQUEST); } //  .  ... } } 

验证对流明的反应


在Lumen上,我们采用与Laravel示例相同的方式进行所有操作,除了我们需要在bootstrap / app.php中注册配置( recaptcha.php ):


 $app->configure('recaptcha'); 

结论


因此,在本文中,您学习了如何在Vue项目中使用Google reCAPTCHA。


ReCAPTCHA是一个很棒的免费工具,可以保护您的资源免受机器人的攻击。
使用隐形验证码,您可以检查访客,而无需他们采取任何行动。


来自Codepen的文章中的示例应用程序


使用的来源:


  1. https://github.com/DanSnow/vue-recaptcha
  2. https://developers.google.com/recaptcha/docs/invisible
  3. https://developers.google.com/recaptcha/docs/verify
  4. https://security.stackexchange.com/questions/78807/how-does-googles-no-captcha-recaptcha-work

Source: https://habr.com/ru/post/zh-CN443370/


All Articles