假设您正在构建一个即将启动的 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中文网其他相关文章!

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

记事本++7.3.1
好用且免费的代码编辑器