假设您正在构建一个即将启动的 Web 应用程序。您精心设计了用户界面,添加了令人兴奋的功能,并确保一切顺利运行。但随着发布日期的临近,一个挥之不去的问题开始让你担心——安全性。具体来说,如何确保只有正确的用户才能访问应用程序的正确部分。这就是身份验证的用武之地。
身份验证是验证用户身份的过程,是 Web 开发的一个关键方面。在广阔的数字环境中,确保用户可以安全地登录和注销您的应用程序至关重要。一不小心,您的应用程序就可能容易受到攻击,从而使用户数据面临风险。
介绍
在本文中,我们将探索 Node.js 中的安全身份验证,使用 bcrypt.js 哈希密码和 JWT 令牌来管理用户会话。最后,您将深入了解如何实施强大的登录/注销系统,确保用户数据的安全。
所以,让我们踏上构建防弹身份验证系统的旅程,从设置我们的环境到使用 JWT 保护我们的路由。准备好锁定您的 Node.js 应用程序了吗?让我们开始吧。
设置 Node.js 项目环境
首先,使用 npm init -y 初始化 Node.js 项目,这会创建一个具有默认设置的 package.json 文件。接下来,安装必要的软件包:用于设置服务器的express、用于管理MongoDB的mongoose、用于处理JWT令牌的jsonwebtoken、用于散列密码的bcryptjs、用于环境变量的dotenv、用于启用跨域资源共享的cors、用于解析cookie的cookie-parser。最后,添加nodemon作为开发依赖,以便在代码更改时自动重启服务器。
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
现在修改package.json文件。添加像我的代码和类型这样的脚本。
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
基本服务器设置
接下来,我们将设置一个基本的 Express 服务器。创建一个名为 index.js 的文件。此代码初始化 Express 并创建应用程序的实例。然后,我们将为根 URL (“/”) 定义一个路由来处理传入的 HTTP GET 请求。之后,我们将在端口 8000 上启动服务器,使其能够侦听传入请求。
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
设置基本身份验证路由
现在,我们将创建一个名为“routes”的文件夹,并在该文件夹中创建一个名为 authRoute.js 的新文件,并粘贴以下代码以查看路由的基础知识。
在此代码片段中,我们使用 Express 设置不同身份验证端点的路由。首先,我们导入express库并创建一个新的路由器实例。然后,我们定义三个 GET 路由:/signup、/login 和 /logout,每个路由都使用一个 JSON 对象进行响应,指示相应的端点已被命中。最后,我们将路由器实例导出为默认导出,使其可用于应用程序的其他部分。
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
现在更改 index.js 添加身份验证路由来测试您的端点。
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
现在,您可以在浏览器中测试它......但为了方便起见,我将使用 Postman。您可以像这样测试所有端点。
类似地,您可以看到其他路线,例如注销和注册。
所以,我们的基本应用程序已准备就绪......现在使其成为一个强大且正确的身份验证系统。
使用 Mongoose 架构创建用户模型
现在,首先准备好我们的 mongoDB 数据库。为此,创建一个文件夹 Model,并在该文件夹下创建一个文件 User.js,并在此文件中为 mongoDB 数据库中的用户添加 Mongoose 架构和模型。该架构包括用户名、全名、密码和电子邮件字段,每个字段都具有指定的数据类型和约束,例如唯一性和所需状态。密码字段的最小长度也为 6 个字符。
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
使用 Mongoose 连接到 MongoDB
现在让我们连接到我们的数据库。我们将创建一个名为 db 的文件夹,并在其中创建一个名为 connectDB.js 的文件。在此文件中,我们将定义一个异步函数 connectMongoDB,它尝试使用 Mongoose 连接到 MongoDB 数据库。它从 MONGO_URI 环境变量获取数据库连接字符串。如果连接成功,它将记录一条包含主机名的成功消息。如果失败,它会记录错误并以状态代码 1 退出进程。该函数将被导出以供应用程序的其他部分使用。
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
现在要使用 MONGO_URI,我们必须将其放入 .env 文件中。这里我使用了本地 mongoDB 设置连接字符串。如果你愿意,你也可以使用 mongoDB atlas。
import express from "express"; import authRoute from "./routes/authRoutes.js"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.use("/api/auth", authRoute); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
注册功能
现在实现注册功能。对于这第一个,创建一个文件夹控制器和文件 authController.js
import mongoose from "mongoose"; // Define the User schema with various fields and their data types const userSchema = new mongoose.Schema( { // The unique username of the user username: { type: String, required: true, unique: true, }, fullName: { type: String, required: true, }, // The password of the user (min length: 6) password: { type: String, required: true, minLength: 6, }, // The email of the user (unique) email: { type: String, required: true, unique: true, }, }, { timestamps: true } ); // Create the User model based on the userSchema const User = mongoose.model("User", userSchema); // Export the User model export default User;
首先,它从请求正文中提取全名、用户名、电子邮件和密码。它使用正则表达式验证电子邮件格式,如果格式无效,则返回 400 状态。
接下来,该函数检查用户名或电子邮件是否已存在于数据库中。如果采取任一操作,则会返回带有错误消息的 400 状态。它还确保密码长度至少为 6 个字符,如果不满足此条件,则会发送另一个 400 状态。
然后使用 bcrypt 对密码进行安全哈希处理。使用提供的数据创建一个新的 User 实例并将其保存到数据库中。
保存后,该函数会生成一个 JWT 令牌,将其设置为 cookie,并返回 201 状态以及用户的 ID、全名、用户名和电子邮件。如果发生任何错误,则会将其记录下来,并发送 500 状态和“内部服务器错误”消息。
要激活此功能,您必须导入这些
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
注意到什么了吗?一个名为 generateTokenAndSetCookie 的新东西...让我们看看它的代码...创建一个文件夹 utils,其中包含generateTokenAndSetCookie.js。
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
**generateTokenAndSetCookie **函数创建一个 JWT 并将其存储在 cookie 中以用于用户身份验证。
JWT 一代:
该函数使用 jsonwebtoken 库创建 JWT。它使用用户的 ID 和密钥(来自环境变量的 JWT_SECRET)对令牌进行签名,并将其设置为在 15 天后过期。
设置 Cookie:
然后该令牌将存储在用户浏览器上的 cookie 中。 cookie 配置了几个安全属性:
- maxAge:将 cookie 的生命周期设置为 15 天。
- httpOnly:确保 cookie 无法通过 JavaScript 访问,从而防止 XSS(跨站脚本)攻击。
- sameSite: "strict":通过限制 cookie 仅与来自同一站点的请求一起发送来防止 CSRF(跨站点请求伪造)攻击。
- 安全:如果环境不是开发,则确保仅通过 HTTPS 发送 cookie,增加额外的安全层。
因此该函数可确保用户会话的安全性和持久性,使其成为身份验证过程的关键部分。
这里我们必须在.env中添加另一个环境变量JWT_SECRET。您可以像这样添加任何类型的数字和字符串混合。
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
现在我们的注册功能已经完成..所以现在就开始它的路线。
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
好的,现在让我们修改我们的index.js,在这里我们添加了一些新的导入。 dotenv: 从 .env 安全地加载环境变量; express.json(): 解析传入的 JSON 请求; express.urlencoded({ Extended: true }): 解析 URL 编码数据; cookieParser: 处理 JWT 令牌的 cookie; connectMongoDB(): 连接MongoDB进行数据存储; 路由: /api/auth 管理注册、登录和注销。
这里是index.js的更新代码
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
所以。现在是时候在 Postman 中测试我们的注册功能了。让我们看看它是否有效。
所以,这是结果。
在这里你可以看到它工作正常,你也可以检查你的 mongoDB 数据库。
登录功能
现在制作登录功能。让我们再次回到我们的 authController.js 文件
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
登录控制器通过验证用户名和密码来验证用户身份。它首先使用用户名在数据库中搜索用户。如果找到,它会使用 bcrypt 将提供的密码与存储在数据库中的散列密码进行比较。如果用户名或密码不正确,则返回错误响应。验证成功后,它会生成一个 JWT 令牌,使用generateTokenAndSetCookie 将其设置为 cookie,并返回一条成功消息,表明用户已成功登录。
让我们在 authRoutes.js 中添加登录路由
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
让我们在 Postman 中测试一下。
这里可以看到已经成功显示登录了。
注销功能
好的。现在是最后一个功能,即注销功能。让我们来实现这个。很简单。
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
注销控制器通过使用 res.cookie 从客户端浏览器清除 JWT cookie,将其值设置为空字符串并将 maxAge 设置为 0,确保立即过期,从而安全地注销用户。成功清除 cookie 后,它会发送成功响应,并显示一条消息,指示用户已成功注销。如果在此过程中发生任何错误,它会捕获错误、记录错误并返回内部服务器错误响应。
将此路由添加到我们的 authRoute.js
import express from "express"; import authRoute from "./routes/authRoutes.js"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.use("/api/auth", authRoute); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
好的。让我们测试一下我们的最后一个功能,看看它是否工作正常。
哦!…运行得非常好。 ??
所以,现在我们完整的身份验证后端已准备就绪。 ??
我的 npm 包
如果您不想自己编写所有代码并想要一个快速解决方案,我创建了一个名为 auth0_package 的 npm 包。你可以从这里获取。
Github 存储库
您可以在此处的 github 存储库中获取我的上述所有代码。
现在您的后端应用程序已完成。在下一篇博客中,我将解释如何将其与您的前端集成。所以请继续关注??.
结论
总之,在 Node.js 应用程序中实现安全身份验证对于保护用户数据并确保只有授权用户才能访问应用程序的特定部分至关重要。通过使用 bcrypt.js 进行密码哈希处理并使用 JWT 令牌进行会话管理,您可以创建一个强大的登录/注销系统。这种方法不仅增强了安全性,而且提供了无缝的用户体验。设置 MongoDB 数据库并使用 Express 进行路由进一步增强了后端基础设施。借助这些工具和技术,您可以放心地启动您的 Web 应用程序,因为您知道它受到了很好的保护,可以防止未经授权的访问和潜在的安全威胁。
以上是掌握 Node.js 中的安全身份验证:使用 bcrypt.js 和 JWT 登录/注销的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

将矩阵电影特效带入你的网页!这是一个基于著名电影《黑客帝国》的酷炫jQuery插件。该插件模拟了电影中经典的绿色字符特效,只需选择一张图片,插件就会将其转换为充满数字字符的矩阵风格画面。快来试试吧,非常有趣! 工作原理 插件将图片加载到画布上,读取像素和颜色值: data = ctx.getImageData(x, y, settings.grainSize, settings.grainSize).data 插件巧妙地读取图片的矩形区域,并利用jQuery计算每个区域的平均颜色。然后,使用

本文讨论了使用浏览器开发人员工具的有效JavaScript调试,专注于设置断点,使用控制台和分析性能。

本文将引导您使用jQuery库创建一个简单的图片轮播。我们将使用bxSlider库,它基于jQuery构建,并提供许多配置选项来设置轮播。 如今,图片轮播已成为网站必备功能——一图胜千言! 决定使用图片轮播后,下一个问题是如何创建它。首先,您需要收集高质量、高分辨率的图片。 接下来,您需要使用HTML和一些JavaScript代码来创建图片轮播。网络上有很多库可以帮助您以不同的方式创建轮播。我们将使用开源的bxSlider库。 bxSlider库支持响应式设计,因此使用此库构建的轮播可以适应任何

数据集对于构建API模型和各种业务流程至关重要。这就是为什么导入和导出CSV是经常需要的功能。在本教程中,您将学习如何在Angular中下载和导入CSV文件

核心要点 利用 JavaScript 增强结构化标记可以显着提升网页内容的可访问性和可维护性,同时减小文件大小。 JavaScript 可有效地用于为 HTML 元素动态添加功能,例如使用 cite 属性自动在块引用中插入引用链接。 将 JavaScript 与结构化标记集成,可以创建动态用户界面,例如无需页面刷新的选项卡面板。 确保 JavaScript 增强功能不会妨碍网页的基本功能至关重要;即使禁用 JavaScript,页面也应保持功能正常。 可以使用高级 JavaScript 技术(


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver CS6
视觉化网页开发工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

WebStorm Mac版
好用的JavaScript开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。