身份验证是Web开发的重要组成部分。JSON Web令牌(JWT)由于其简单性,安全性和可扩展性,已成为在Web应用程序中实现身份验证的流行方法。在这篇文章中,我将指导你在Node.js应用程序中使用MongoDB进行数据存储来实现JWT身份验证。
在开始之前,我假设你已经安装了Node.js、MongoDB和VS Code,并且你知道如何创建MongoDB数据库和基本的RESTful API。
JWT身份验证依赖于JSON Web令牌来确认Web应用中用户的身份。JSON Web令牌是使用密钥对进行数字签名的编码JSON对象。
简而言之,JWT身份验证就像为网站提供一个密码。一旦你登录成功,你就得到了这个密码。
JSON Web Token由三部分组成,由点(.)分隔:
以下是JWT的基本结构:
xxxx.yyyy.zzzz
当你登录成功时,你会得到这个代码。每次你想访问某个数据时,你都要携带这个代码来证明是你。系统会检查代码是否有效,然后让你获取数据!
接下来让我们看看在node.js项目中进行JWT身份验证的步骤。
首先为您的项目创建一个新目录,并使用以下命令进入到该目录。
mkdir nodejs-jwt-authcd nodejs-jwt-auth
通过在终端中运行以下命令初始化项目(确保您位于新创建的项目文件夹中)。
npm init -y
接下来通过以下命令安装必要的依赖项:
npm install express mongoose jsonwebtoken dotenv
上面的命令将安装:
现在您的package.json文件应该看起来像这样:
图片
要连接MongoDB数据库,请查看以下链接中的具体操作流程。
https://shefali.dev/restful-api/#Step_4_Creating_a_MongoDB_Database
为了 MongoDB 连接地址的安全,让我们在根目录下创建一个名为 .env 的新文件。
将以下代码添加到.env文件中。
MONGODB_URL=<Your MongoDB Connection String>SECRET_KEY="your_secret_key_here"
将<Your MongoDB Connection String>替换为您从MongoDB Atlas获得的连接字符串(在步骤2中),并将your_secret_key_here替换为您想要的密钥字符串。现在你的.env文件应该是这样的。
MONGODB_URL='mongodb+srv://shefali:********@cluster0.sscvg.mongodb.net/nodejs-jwt-auth'SECRET_KEY="ThisIsMySecretKey"
在MONGODB_URL最后我们加入node.js-jwt-auth,这是我们的数据库名称。
在根目录下创建一个名为index.js的文件,并将以下代码添加到该文件中。
const express = require("express");const mongoose = require("mongoose");require("dotenv").config(); //for using variables from .env file.const app = express();const port = 3000;//middleware provided by Express to parse incoming JSON requests.app.use(express.json()); mongoose.connect(process.env.MONGODB_URL).then(() => { console.log("MongoDB is connected!");});app.get("/", (req, res) => { res.send("Hello World!");});app.listen(port, () => { console.log(`Server is listening on port ${port}`);});
现在我们可以通过以下命令运行服务器。
node index.js
输出应如下图所示。
图片
通过使用命令node index.js,您必须在每次更改文件时重新启动服务器。为了避免这种情况,您可以使用以下命令安装nodemon。
npm install -g nodemon
现在使用下面的命令运行服务器,它会在每次更改文件时自动重新启动服务器。
nodemon index.js
在根目录下创建一个名为models的新目录,并在其中创建一个名为User.js的新文件。
图片
现在让我们为我们的项目创建一个简单的模型,将以下代码添加到User.js文件中。
const mongoose = require("mongoose");const userSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true, }, password: { type: String, required: true, },});module.exports = mongoose.model("User", userSchema);
在根目录中,创建一个名为routes的新目录,并在其中创建一个名为auth.js的文件。
图片
然后将以下代码添加到该文件中:
const express = require("express");const jwt = require("jsonwebtoken");const User = require("../models/User");const router = express.Router();// Signup routerouter.post("/signup", async (req, res) => { try { const { username, password } = req.body; const user = new User({ username, password }); await user.save(); res.status(201).json({ message: "New user registered successfully" }); } catch (error) { res.status(500).json({ message: "Internal server error" }); }});// Login routerouter.post("/login", async (req, res) => { const { username, password } = req.body; try { const user = await User.findOne({ username }); if (!user) { return res.status(401).json({ message: "Invalid username or password" }); } if (user.password !== password) { return res.status(401).json({ message: 'Invalid username or password' }); } // Generate JWT token const token = jwt.sign( { id: user._id, username: user.username }, process.env.SECRET_KEY ); res.json({ token }); } catch (error) { res.status(500).json({ message: "Internal server error" }); }});module.exports = router;
导入依赖:
const express = require("express");const jwt = require("jsonwebtoken");const User = require("../models/User");const router = express.Router();
在这里,我们导入以下依赖项:
注册路由:
// Signup routerouter.post("/signup", async (req, res) => { try { const { username, password } = req.body; const user = new User({ username, password }); await user.save(); res.status(201).json({ message: "New user registered successfully" }); } catch (error) { res.status(500).json({ message: "Internal server error" }); }});
登录路由:
// Login routerouter.post("/login", async (req, res) => { const { username, password } = req.body; try { const user = await User.findOne({ username }); if (!user) { return res.status(401).json({ message: "Invalid username or password" }); } if (user.password !== password) { return res.status(401).json({ message: 'Invalid username or password' }); } // Generate JWT token const token = jwt.sign( { id: user._id, username: user.username }, process.env.SECRET_KEY ); res.json({ token }); } catch (error) { res.status(500).json({ message: "Internal server error" }); }});
最后路由被导出以在index.js文件中使用。
module.exports = router;
在根目录中,创建一个名为middleware.js的新文件,并将以下代码添加到该文件中。
const jwt = require("jsonwebtoken");function verifyJWT(req, res, next) { const token = req.headers["authorization"]; if (!token) { return res.status(401).json({ message: "Access denied" }); } jwt.verify(token, process.env.SECRET_KEY, (err, data) => { if (err) { return res.status(401).json({ message: "Failed to authenticate token" }); } req.user = data; next(); });}module.exports = verifyJWT;
此代码是一个中间件函数,用于在应用程序中验证JSON Web令牌(JWT)。
分解上面的代码:
现在要验证JWT,请修改index.js,如下所示:
const express = require('express');const authRouter = require('./routes/auth');const mongoose = require("mongoose");const verifyJWT = require("./middleware")require("dotenv").config(); //for using variables from .env file.const app = express();const PORT = 3000;mongoose.connect(process.env.MONGODB_URL).then(() => { console.log("MongoDB is connected!");});app.use(express.json());//Authentication routeapp.use('/auth', authRouter);//decodeDetails Routeapp.get('/decodeDetails', verifyJWT, (req, res) => { const { username } = req.user; res.json({ username });});app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`);});
在上面的代码中,/auth路由是authRouter处理,其中包含的终端用户认证,例如登录和注册。
app.get('/decodeDetails', verifyJWT, (req, res) => { const { username } = req.user; res.json({ username });});
向http://localhost:3000/auth/signup发送一个POST请求,其中包含Headers Content-Type : application/json和以下JSON主体:
{ "username": "shefali", "password": "12345678"}
在响应中,您将看到消息“新用户注册成功”。
向http://localhost:3000/auth/login发送一个POST请求,其中包含Header Content-Type : application/json和JSON主体以及用户名和密码,这是您在注册路由中创建的。
{ "username": "shefali", "password": "12345678"}
在响应中,您将收到一个令牌。记下这个令牌,因为在测试decodeDetails路由时需要它。
向http://localhost:3000/decodeDetails发送一个GET请求,并带有一个带有令牌值的Authorization头(您在测试登录路由时得到了它)。
在响应中,您将获得用户名。恭喜你!
本文链接:http://www.28at.com/showinfo-26-71944-0.htmlNodejs - 九步开启JWT身份验证
声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。