如何在您的 React 应用程序中实现 Google 身份验证!!

2025-05-26

如何在您的 React 应用程序中实现 Google 身份验证!!

简介

大家好!
你有没有想过如何在 React 应用程序中实现 Google 身份验证?不用担心,今天我将向你展示具体的操作方法。

但是,为什么需要它?

OAuth 是一种开放标准授权协议,它允许应用程序访问用户数据,而无需将用户密码共享给其他应用程序。它还使开发者和用户的身份验证过程更加便捷。例如,您可能在某些网站上看到过“使用 Google 登录”按钮。当您点击该按钮时,系统会向 Google 服务器发出请求,并将用户数据(不含密码)返回到客户端。此响应也可以用于我们自己的 API 来验证用户身份。

谷歌登录

我们要做什么?

我们将创建一个 React 应用,它将使用 Google OAuth 来验证用户身份。为了简化应用,我将把用户数据存储在组件状态中。

您将学到什么?

  • 在你的 React 应用中实现 Google 身份验证(非常明显😅)
  • 创建 Node REST API 💻
  • 在客户端和服务器端使用 TypeScript

文件夹结构

客户端

📦客户端
┣ 📂 公共
┣ 📂 src
┃ ┣ 📂 组件
┃ ┃ ┣ 📜 GoogleAuth.tsx
┃ ┣ 📂 页面
┃ ┃ ┃ ┗ 📜 Login.tsx ┃ ┣
📜 App.tsx
┃ ┣ 📜 index.tsx
┃ ┣ 📜 .env

服务器端

📦服务器
┣📂src┃┣📂
控制器
┃┃┗📜auth.controller.ts┃┣📂
模型
┃┃┗📜user.model.ts┃┣📂
路由
┃┃┗📜auth.route.ts┃┗📜index.ts┣📜.env

出发啦!!🏃

创建 Google Cloud 项目

前往Google 开发者控制台。创建一个新项目。您需要配置OAuthc 同意屏幕。为您的应用程序命名,设置用户支持的电子邮件、应用程序徽标等。转到“凭据”选项卡并创建凭据。
选择“OAuth 客户端 ID”,并将应用程序类型选择为 Web。
为您的应用程序命名,并提及授权的 JavaScript 来源和重定向来源。
您将获得您的客户端 ID。将此客户端 ID 保存为客户端和服务器的 .env 文件。

谷歌控制台

初始项目设置

首先,我们需要设置后端并创建一个 REST API 来验证用户身份。创建一个名为server 的文件夹,并在其中初始化一个空项目。



yarn init -y

OR

npm init -y


Enter fullscreen mode Exit fullscreen mode

安装以下依赖项。



yarn add cors dotenv express google-auth-library mongoose


Enter fullscreen mode Exit fullscreen mode

由于我已经提到我们将在应用程序中使用 TypeScript,因此我们需要为这些依赖项安装类型定义。我们将这些类型定义安装为开发依赖项,因为它们在生产环境中不需要。



yarn add @types/cors @types/express @types/mongoose -D


Enter fullscreen mode Exit fullscreen mode

我们还需要nodemonts-nodetypescript,让我们也安装它们



yarn add nodemon ts-node typescript -D


Enter fullscreen mode Exit fullscreen mode

接下来,我们需要生成一个tsconfig.json文件。此文件包含我们 TypeScript 项目的所有配置,例如 rootDir、编译器选项等。



npx tsc --init


Enter fullscreen mode Exit fullscreen mode

我们需要在tsconfig.json文件中做一些更改

tsconfig.jsona
tsconfig.json

另外,将以下脚本添加到你的package.json



"scripts": {
    "dev": "nodemon ./src/index.ts",
    "build": "rm -rf && tsc"
  },


Enter fullscreen mode Exit fullscreen mode

创建快速服务器

在创建快速服务器之前,我想向您展示我们如何创建快速服务器的总体流程图。

流程图

创建一个文件src/index.ts,并在其中创建一个基本的快速服务器。



import express from "express";
import authRoutes from "./routes/auth.route";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";

dotenv.config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());
app.use("/auth", authRoutes);

mongoose.connect(`${process.env.MONGO_URI}`);

const db = mongoose.connection;
db.once("open", () => console.log("Connected to Mongo DB!!"));
db.on("error", (error) => console.error(error));

app.listen(PORT, () =>
  console.log(`The server is up and running on PORT ${PORT} 🚀`)
);


Enter fullscreen mode Exit fullscreen mode

让我向你解释一下这里发生的事情,



import express from "express";
import authRoutes from "./routes/auth.route";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";

dotenv.config();


Enter fullscreen mode Exit fullscreen mode

首先,我们导入所有这些依赖项并配置 dotenv 来加载我们的环境变量。



app.use(cors());
app.use(express.json());
app.use("/auth", authRoutes);


Enter fullscreen mode Exit fullscreen mode

然后我们在这里定义一些中间件。我们创建一个中间件来使用 cors()。第二个中间件将帮助我们通过请求接收 JSON 数据。第三个中间件是路由中间件。



const db = mongoose.connection;
db.once("open", () => console.log("Connected to Mongo DB!!"));
db.on("error", (error) => console.error(error));

app.listen(PORT, () =>
  console.log(`The server is up and running on PORT ${PORT} 🚀`)
);


Enter fullscreen mode Exit fullscreen mode

然后我们最终连接到我们的 MongoDB 数据库并在端口 5000 上监听我们的 express 服务器。

用户模型

接下来,我们需要创建一个用户模型,将用户文档保存到数据库中。创建一个models/user.model.ts文件。



import mongoose from "mongoose";

interface UserDocument extends mongoose.Document {
  email: string;
  avatar: string;
  name: string;
}

const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
  },
  avatar: {
    type: String,
    default: "",
  },
  name: {
    type: String,
    required: true,
  },
});

export default mongoose.model<UserDocument>("User", UserSchema);


Enter fullscreen mode Exit fullscreen mode

请注意,我们在这里仅实现 google 身份验证,因此我没有在这里指定密码字段,但是如果您自己创建身份验证系统,您可能也希望有一个密码字段。

控制器

我们必须创建一个控制器来验证我们的用户并将响应发送回客户端。

创建文件controllers/auth.controller.ts



import { Request, Response } from "express";
import { OAuth2Client } from "google-auth-library";
import User from "../models/user.model";

const googleClient = new OAuth2Client({
  clientId: `${process.env.GOOGLE_CLIENT_ID}`,
});

export const authenticateUser = async (req: Request, res: Response) => {
  const { token } = req.body;

  const ticket = await googleClient.verifyIdToken({
    idToken: token,
    audient: `${process.env.GOOGLE_CLIENT_ID}`,
  });

  const payload = ticket.getPayload();

  let user = await User.findOne({ email: payload?.email });
  if (!user) {
    user = await new User({
      email: payload?.email,
      avatar: payload?.picture,
      name: payload?.name,
    });

    await user.save();
  }

  res.json({ user, token });
};


Enter fullscreen mode Exit fullscreen mode

让我解释一下这里发生的事情。



import { Request, Response } from "express";
import { OAuth2Client } from "google-auth-library";
import User from "../models/user.model";

const googleClient = new OAuth2Client({
  clientId: `${process.env.GOOGLE_CLIENT_ID}`,
});


Enter fullscreen mode Exit fullscreen mode

首先,我们导入所有必要的依赖项和库,然后使用从 google 收到的客户端 ID 初始化我们的 google 客户端。

接下来,我们创建并导出一个authenticateUser函数,它基本上是我们的控制器。

在authenticUser函数中,我们从req.body中获取 token 。(我们将从客户端发送 token)



const { token } = req.body;


Enter fullscreen mode Exit fullscreen mode


const ticket = await googleClient.verifyIdToken({
  idToken: token,
  audient: `${process.env.GOOGLE_CLIENT_ID}`,
});

const payload = ticket.getPayload();


Enter fullscreen mode Exit fullscreen mode

然后我们验证令牌并获取包含用户详细信息的有效负载。



let user = await User.findOne({ email: payload?.email });
if (!user) {
  user = await new User({
    email: payload?.email,
    avatar: payload?.picture,
    name: payload?.name,
  });

  await user.save();
}

res.json({ user, token });


Enter fullscreen mode Exit fullscreen mode

接下来,我们检查从 Google 收到的用户是否已存在于我们的数据库中。如果存在,则返回相同的用户以及令牌;否则,我们将在数据库中创建并保存一个新用户。

路线

现在,我们需要在服务器访问/auth端点时运行此控制器。为此,我们需要指定到 Express 服务器的路由。创建一个routes/auth.route.ts文件。导入该控制器并将其指定为/ POST 路由。



import express from "express";
import { authenticateUser } from "../controllers/auth.controller";

const router = express.Router();

router.post("/", authenticateUser); // (This is actually /auth POST route)

export default router;


Enter fullscreen mode Exit fullscreen mode

客户端

现在,我们已经准备好了后端,是时候开始处理前端了。初始化一个 React 应用。



yarn create react-app --typescript google-login-project
cd google-login-project


Enter fullscreen mode Exit fullscreen mode

安装以下依赖项



yarn add react-google-login react-router-dom axios
yarn add @types/react-router-dom -D


Enter fullscreen mode Exit fullscreen mode

创建 UI

让我们为应用程序创建 UI。在App.tsx中进行以下更改



import { Switch, Route } from "react-router-dom";
import GoogleAuth from "./components/GoogleAuth";

const App = () => {
  return <GoogleAuth />;
};

export default App;


Enter fullscreen mode Exit fullscreen mode

GoogleAuth 组件

App.tsx中,您已经看到我们使用了 GoogleAuth 组件。让我们在 components 目录中创建它。



// /components/GoogleAuth.tsx
import { useState } from "react";
import axios, { AxiosResponse } from "axios";
import GoogleLogin from "react-google-login";

interface AuthResponse {
  token: string;
  user: User;
}

interface User {
  _id: string;
  name: string;
  email: string;
  avatar: string;
}

const GoogleAuth = () => {
  const [user, setUser] = useState<User | null>(null);
  const onSuccess = async (res: any) => {
    try {
      const result: AxiosResponse<AuthResponse> = await axios.post("/auth/", {
        token: res?.tokenId,
      });

      setUser(result.data.user);
    } catch (err) {
      console.log(err);
    }
  };

  return (
    <div className="h-screen w-screen flex items-center justify-center flex-col">
      {!user && (
        <GoogleLogin
          clientId={`${process.env.REACT_APP_CLIENT_ID}`}
          onSuccess={onSuccess}
        />
      )}

      {user && (
        <>
          <img src={user.avatar} className="rounded-full" />
          <h1 className="text-xl font-semibold text-center my-5">
            {user.name}
          </h1>
        </>
      )}
    </div>
  );
};

export default GoogleAuth;


Enter fullscreen mode Exit fullscreen mode

由于这是一个简单的应用程序,我在这里使用了条件渲染而不是路由。如果用户未设置状态,我们将渲染 Google 登录组件,否则将显示用户的详细信息(头像和姓名)。

但是,如果您愿意,您可以将用户的数据存储在 redux 存储或 Context API 中,这似乎更实用。

总结✨

就是这样。我们已经成功在 React 应用程序中实现了 Google OAuth。Github
仓库:https://github.com/shaan-alam/google-login

在这里找到我🌍

Github - shaan-alam
Twitter - shaancodes
LinkedIn - Shaan Alam
Instagram - shaancodes

文章来源:https://dev.to/shaancodes/how-to-implement-google-authentication-in-your-react-applications-jb6
PREV
🎉5 项有助于提升 2020 年薪资的开发技能
NEXT
如何使用 Next.JS 构建我的第二个大脑