如何在您的 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
安装以下依赖项。
yarn add cors dotenv express google-auth-library mongoose
由于我已经提到我们将在应用程序中使用 TypeScript,因此我们需要为这些依赖项安装类型定义。我们将这些类型定义安装为开发依赖项,因为它们在生产环境中不需要。
yarn add @types/cors @types/express @types/mongoose -D
我们还需要nodemon、ts-node和typescript,让我们也安装它们
yarn add nodemon ts-node typescript -D
接下来,我们需要生成一个tsconfig.json文件。此文件包含我们 TypeScript 项目的所有配置,例如 rootDir、编译器选项等。
npx tsc --init
我们需要在tsconfig.json文件中做一些更改。
另外,将以下脚本添加到你的package.json
"scripts": {
"dev": "nodemon ./src/index.ts",
"build": "rm -rf && tsc"
},
创建快速服务器
在创建快速服务器之前,我想向您展示我们如何创建快速服务器的总体流程图。
创建一个文件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} 🚀`)
);
让我向你解释一下这里发生的事情,
import express from "express";
import authRoutes from "./routes/auth.route";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";
dotenv.config();
首先,我们导入所有这些依赖项并配置 dotenv 来加载我们的环境变量。
app.use(cors());
app.use(express.json());
app.use("/auth", authRoutes);
然后我们在这里定义一些中间件。我们创建一个中间件来使用 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} 🚀`)
);
然后我们最终连接到我们的 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);
请注意,我们在这里仅实现 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 });
};
让我解释一下这里发生的事情。
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}`,
});
首先,我们导入所有必要的依赖项和库,然后使用从 google 收到的客户端 ID 初始化我们的 google 客户端。
接下来,我们创建并导出一个authenticateUser函数,它基本上是我们的控制器。
在authenticUser函数中,我们从req.body中获取 token 。(我们将从客户端发送 token)
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 });
接下来,我们检查从 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;
客户端
现在,我们已经准备好了后端,是时候开始处理前端了。初始化一个 React 应用。
yarn create react-app --typescript google-login-project
cd google-login-project
安装以下依赖项
yarn add react-google-login react-router-dom axios
yarn add @types/react-router-dom -D
创建 UI
让我们为应用程序创建 UI。在App.tsx中进行以下更改
import { Switch, Route } from "react-router-dom";
import GoogleAuth from "./components/GoogleAuth";
const App = () => {
return <GoogleAuth />;
};
export default App;
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;
由于这是一个简单的应用程序,我在这里使用了条件渲染而不是路由。如果用户未设置状态,我们将渲染 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