likes
comments
collection
share

如何在React应用中实现reCAPTCHA

作者站长头像
站长
· 阅读数 41

在这篇文章中,我们将演示如何在React应用程序中实现reCAPTCHA v2,以及如何在Node.js后端验证用户令牌。

前提条件

要跟上本文教程部分的例子,你应该具备以下基础知识。

  • React和它的概念
  • 用Node.js和Express.js创建服务器
  • HTTP请求

什么是CAPTCHA?

CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)是一种挑战-回应安全措施,旨在区分真实网站用户和自动用户,如机器人。

许多网络服务使用CAPTCHAs来帮助防止不正当和非法的活动,如垃圾邮件和密码解密。验证码要求用户完成一个简单的测试,以证明他们是人类而不是机器人,然后才让他们访问敏感信息。

什么是reCAPTCHA?

有几种类型的验证码系统,但最广泛使用的系统是reCAPTCHA,这是谷歌的一个工具。Duolingo的联合创始人Luis von Ahn早在2007年就创建了这个工具,目前有超过600万个网站在使用,包括BBC、彭博社和Facebook。

reCAPTCHA的第一个版本是由随机生成的扭曲的字母和数字字符序列和一个文本框组成。

如何在React应用中实现reCAPTCHA

developers.google.com/recaptcha/o…

为了通过测试,用户需要解读扭曲的字符并将其输入文本框。虽然计算机能够创建图像并产生响应,但它们不能像人那样阅读或解释信息以通过测试。

reCAPTCHA为用户的每个请求生成一个响应令牌,并将其发送到谷歌的API进行验证。API会返回一个分数,以确定该用户是人类还是自动程序。

reCAPTCHA目前有两个工作版本:V2和V3。虽然v3是reCAPTCHA的最新版本(2018年发布),但大多数网站仍然使用2014年发布的reCAPTCHA v2。

reCAPTCHA v2有两个变体:复选框和不可见。复选框变体,也被称为 "我不是机器人",是最受欢迎的。这个变体的一个选项显示一个复选框小部件,用户可以与之互动,以验证他们的身份。

如何在React应用中实现reCAPTCHA

不可见的变体显示一个reCAPTCHA徽章,表明该服务在后台运行。

在某些情况下,如果用户的行为引发怀疑,reCAPTCHA v2将提供一个挑战,用户必须通过,以证明他们不是一个机器人。

如何在React应用中实现reCAPTCHA

在React中实施reCAPTCHA

现在我们了解了reCAPTCHA是什么,让我们看看如何在React应用程序中实现它。但首先,我们需要在谷歌reCAPTCHA控制台中为我们的应用程序注册一个API密钥。该密钥对由两个密钥组成:网站密钥和秘密密钥。

网站密钥在我们的应用程序中调用reCAPTCHA服务。秘密密钥验证用户的回应。它通过授权我们应用程序的后台和reCAPTCHA服务器之间的通信来实现这一目的。

继续并在这里创建你的密钥对。

首先,你需要用你的谷歌账户登录。然后,你会被重定向到管理控制台。接下来,你将填写页面上的注册表,以生成你网站的密钥对。

如何在React应用中实现reCAPTCHA

注册是相当简单的,但为了清楚起见,我将解释每个表格字段的含义以及如何填写每个字段。

密钥对注册

标签

对于标签字段,提供一个名称以帮助你认识你正在创建的配对钥匙的目的。如果你在你的帐户上设置了不止一个配对钥匙,标签将帮助你区分它们。

类型

类型选择器指的是你想在你的网站上使用的reCAPTCHA的版本。你可以选择v3或v2。由于本教程只涉及v2版的实施,请继续选择v2版和 "我不是机器人 "的变体。

域名

域名字段是你设置将与你的reCAPTCHA一起工作的域名的地方。你可以输入一个有效的域名或 "localhost"(如果你的项目仍在开发中),然后点击**+**来添加域名。

业主

所有者字段是你可以向其他人提供对你的应用程序的reCAPTCHA的访问权的地方。默认情况下,你将是所有者,但你可以通过提供他们的谷歌电子邮件来添加更多的人。

一旦你完成了表格字段,检查必要的框,然后点击提交

现在你应该能够看到你的网站密钥和秘密密钥。它们看起来将与这里显示的相似。

如何在React应用中实现reCAPTCHA

接下来,我们将设置一个React示例项目,并使用我们刚刚创建的密钥对实现reCAPTCHA。

设置一个React项目的样本

为了用reCAPTCHA验证用户的输入,我们需要一个能与Google的API通信的服务器。所以我们需要在设置项目时记住这一点。

首先,创建一个文件夹。对于这个示例项目,我将把文件夹命名为react-node-app ,但你可以使用你选择的不同名称。

接下来,在你喜欢的IDE中打开该文件夹,运行以下命令。

npm init -y

这将创建一个package.json 文件,它将帮助我们管理我们的依赖关系并跟踪我们的脚本。

继续用create-react-app ,在终端键入以下命令,启动一个React应用。

npx create-react-app my-app

这个命令将在react-node-app 文件夹中创建一个my-app 文件夹,并将在my-app 文件夹中安装 React。

安装后,打开my-app 文件夹,清理项目文件夹中不必要的模板代码和文件,然后在src 文件夹中创建一个Form.js 组件。

接下来,在表单组件中添加以下代码,并在App.js 主组件内导入。

const Form = () =>{

    return(
        <form>
            <label htmlFor="name">Name</label>
                <input type="text" id="name" className="input"/>
            <button>Submit</button>
        </form>
    )
}

export default Form

上面的代码是一个简单的登录表单,有一个input 元素和一个Submit 按钮。

对表单组件进行造型不是必须的,但如果你想增加一点亮点,可以在项目文件夹中的App.css 文件内添加以下CSS代码。

.input{
  width: 295px;
  height: 30px;
  border: rgb(122, 195, 238) 2px solid;
  display: block;
  margin-bottom: 10px;
  border-radius: 3px;
}

.input:focus{
  border: none;
}

label{
  display: block;
  margin-bottom: 2px;
  font-family: 'Courier New', Courier, monospace;
}

button{
  padding: 7px;
  margin-top: 5px;
  width: 300px;
  background-color: rgb(122, 195, 238);
  border: none;
  border-radius: 4px;
}

现在,在终端中用npm start 命令启动开发服务器。

你应该看到在你的浏览器上显示一个类似于这样的表格。

如何在React应用中实现reCAPTCHA

***注意:*在为生产创建类似的东西时,建议使用支持SSR(服务器端渲染)的框架,如Next.js或Remix。

安装react-google-recaptcha

react-google-recaptcha 库可以在React中整合Google reCAPTCHA v2。该包提供了一个组件,在有用的道具的帮助下简化了React中处理和渲染reCAPTCHA的过程。

要安装react-google-recaptcha,请输入并运行以下命令。

npm install --save react-google-recaptcha

添加reCAPTCHA

安装完react-google-recaptcha ,前往form.js 组件文件并导入它,像这样。

import reCAPTCHA from "react-google-recaptcha"

现在将reCAPTCHA 组件添加到表单中,就在Submit 按钮之前或之后。你的组件的位置是可选的,reCAPTCHA小部件将出现在reCAPTCHA 组件在表单中的位置,当渲染时。

<form >
            <label htmlFor="name">Name</label>
                <input type="text" id="name" className="input"/>
                <reCAPTCHA />
            <button>Submit</button>
</form>

如前所述,reCAPTCHA 组件接受几个道具。然而,sitekey 这个道具是我们渲染该组件时唯一需要的道具。这个道具有助于我们在之前从reCAPTCHA密钥对中生成的站点密钥与reCAPTCHA 组件之间的连接。

下面是reCAPTCHA 组件的其他可选道具。

  • theme:将部件的主题改为lightdark
  • size:改变验证码的大小或类型
  • onErrored: 如果测试返回一个错误,则启动一个回调函数
  • badge改变reCAPTCHA徽章的位置(bottomright,bottomleft, 或inline )。
<reCAPTCHA
sitekey={process.env.REACT_APP_SITE_KEY}
/>

在这里,我们在reCAPTCHA 组件中添加了一个sitekey 道具,并将reCAPTCHA网站密钥传递给它一个环境变量。

要在你的项目中做同样的事情,在你的项目的根文件夹中创建一个.env 文件。接下来,在该文件中添加以下代码。

/*.env*/
REACT_APP_SECRET_KEY = "Your secret key"
REACT_APP_SITE_KEY = "your site key"

这样,你就可以在你的应用程序中安全地使用你的秘钥,在需要它们的地方引用变量名。

现在,如果保存你的代码并进入浏览器,在代码中放置reCAPTCHA组件的地方应该出现一个reCAPTCHA框。在这个例子中,它出现在提交按钮之前。

如何在React应用中实现reCAPTCHA

在每次验证之后,我们需要重置reCAPTCHA,以便进行后续检查。为了达到这个目的,我们需要在reCAPTCHA 组件中添加一个ref 的道具。

要使用ref prop,首先,从React导入useRef hook。

import React, { useRef } from 'react';

接下来,将ref 的值存储在一个变量中,像这样。

const captchaRef = useRef(null)

然后,将ref 道具添加到reCAPTCHA 组件中,并将captchaRef 变量传递给它。

<reCAPTCHA
sitekey={process.env.REACT_APP_SITE_KEY}
ref={captchaRef}
/>

这是我们的Form 组件中到此为止的全部代码。

import reCAPTCHA from "react-google-recaptcha"

const Form = () =>{
    return(
            <form>
                <label htmlFor="name">Name</label>
                    <input type="text" id="name" className="input"/>
                    <reCAPTCHA
                    sitekey={process.env.REACT_APP_SITE_KEY} 
                    ref={captchaRef}
                    />
                <button>Submit</button>
            </form>
    )
}
export default Form

现在我们有了一个工作的部件,我们只需要完成三个步骤就可以让reCAPTCHA发挥作用。

  1. reCAPTCHA 组件中获取响应令牌
  2. 重置reCAPTCHA 组件以进行后续检查
  3. 在后端验证响应令牌

获取响应令牌

我们也可以使用ref ,从我们的reCAPTCHA获得生成的令牌。我们所要做的就是用下面的代码获得ref 的值。

const token = captchaRef.current.getValue();

重置reCAPTCHA以进行后续检查

如果我们将上述代码添加到表单组件中,它实际上会导致一个错误。这是因为ref 的值仍然是空的,因为reCAPTCHA处于未检查的状态。为了解决这个问题,我们我们将在表单中添加一个onSubmit 事件处理程序,用一个函数来封装这些代码。

const handleSubmit = (e) =>{
        e.preventDefault();
        const token = captchaRef.current.getValue();
        captchaRef.current.reset();
    }

return(
        <form onSubmit={handleSubmit} >
            …
        </form>
    )    

在上面的代码中,我们创建了一个handleSubmit 函数。在这个函数里面,我们添加了token 变量,用于从reCAPTCHA获取响应令牌,以及每次提交表单时重置reCAPTCHA的代码。

这样,getValue() 方法将只在点击提交按钮时尝试获取 ref 的值,也就是响应令牌。

现在,如果你将token 变量记录到控制台,勾选reCAPTCHA复选框,然后提交表单,你应该在控制台看到一个类似于下面的生成的响应令牌。

如何在React应用中实现reCAPTCHA

在Node.js后端验证令牌

我们在上一节中生成的令牌只有两分钟的有效期,这意味着我们需要在它过期之前验证它。要做到这一点,我们需要设置我们应用程序的后端,并将令牌发送到谷歌的API,以检查用户的分数。

设置Node.js后端

要设置一个Node.js服务器,请回到react-node-app 文件夹,创建一个新的文件夹,并命名为server 。在server 文件夹内,创建一个新文件,并命名为index.js 。这个文件将作为我们的Node应用程序的入口点。

接下来,cd进入server 文件夹,运行以下命令来安装Express.js和Axios。

npm i express axios dotenv --save

现在,在index.js 文件中添加以下代码。

const express = require("express");
const router = express.Router();
const app = express();
const cors = require('cors');
const axios = require('axios');
const dotenv = require('dotenv').config()
const port = process.env.PORT || 2000;

//enabling cors
app.use(cors());

//Parse data
app.use(express.json());
app.use(express.urlencoded({extended: true}));

//add router in express
app.use("/", router);

//POST route
router.post("/post", async (req, res) => {
//Destructuring response token from request body
    const {token} = req.body;

//sends secret key and response token to google
    await axios.post(
      `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.SECRET_KEY}&response=${token}`
      );

//check response status and send back to the client-side
      if (res.status(200)) {
        res.send("Human 

在上面的代码中,我们设置了一个Express服务器,并为/post 路由创建了一个POST API端点。在端点函数里面,我们对请求主体进行了结构化处理,以获得将从客户端发送的token 数据。

然后,我们向谷歌的API创建了一个axios.post 请求,并将我们的SECRET_KEY 作为一个环境变量传入,以及来自客户端的token

要在Node.js中设置环境变量,cd回到react-node-app 文件夹并运行以下命令。

npm install dotenv --save

安装完成后,在react-node-app 文件夹内创建一个.env 文件,打开该文件,然后添加你网站的秘钥。

axios.post 请求下面是一个if 语句,它检查API返回的响应状态并将其发送到客户端。

好了,让我们继续前进。导航回到react-node-app 文件夹,打开package.json 文件,用下面的内容替换脚本命令。

"scripts": {
  "start": "node server/index.js"
},

上面的代码将让我们在终端运行时使用npm start 命令启动我们的服务器。

保存该项目。然后,到你的终端,打开一个新的终端标签,cd进入server 文件夹,并通过运行npm start 来启动服务器。

检查用户的得分

接下来,我们将从客户端(React应用程序)向我们的服务器发送一个axios.post 请求,将生成的令牌作为数据。

要做到这一点,请回到你的React应用程序,并在我们先前创建的handleSubmit 函数中粘贴以下代码。

 const handleSubmit = async (e) =>{
        e.preventDefault();

        const token = captchaRef.current.getValue();
        captchaRef.current.reset();

        await axios.post(process.env.REACT_APP_API_URL, {token})
        .then(res =>  console.log(res))
        .catch((error) => {
        console.log(error);
        })
    }

这段代码是一个axios.post 请求,将生成的令牌从reCAPTCHA发送到Node.js后端。

如果你保存你的代码并运行应用程序,你应该看到一个类似于这样的reCAPTCHA表单。

如何在React应用中实现reCAPTCHA

这就是了!你已经成功地实现了一个有效的谷歌reCAPTCHA和一个后台服务器,可以在React中验证用户的回应。

总结

在这篇文章中,我们研究了什么是reCAPTCHA以及它是如何工作的。我们还通过一个教程来演示如何在React应用程序中实现reCAPTCHA,以及如何用Node.js后端服务器来验证用户的响应标记。

我希望这篇文章能帮助你构建安全和无僵尸的React应用。

The postHow to implement reCAPTCHA in a React applicationappeared first onLogRocket Blog.