Node.js中JWT實(shí)現(xiàn)身份驗(yàn)證的詳細(xì)步驟
在開始之前,我假設(shè)你已經(jīng)在你的機(jī)器上安裝了Node.js、MongoDB和VS Code,并且你知道如何創(chuàng)建MongoDB數(shù)據(jù)庫和基本的RESTful API。
讓我們開始吧!
什么是JWT認(rèn)證?
JWT身份驗(yàn)證依賴JSON Web令牌來確認(rèn)Web應(yīng)用中用戶的身份。JSON Web令牌是使用密鑰進(jìn)行數(shù)字簽名。
簡而言之,JWT身份為網(wǎng)站提供一個密碼。一旦你登錄,你就得到了這個密碼。
JSON Web Token由三個部分組成,由點(diǎn).
分開:
- Header
- Payload
- Signature
下面是JWT的基本結(jié)構(gòu):
xxxx.yyyy.zzzz
- Header: 這部分包含有關(guān)令牌的信息,如其類型和如何保護(hù)。
- Payload: 這部分包含關(guān)于用戶的聲明,如用戶名或角色。
- Signature: 確保令牌的完整性,并驗(yàn)證它沒有被更改,這可以確保代碼安全。
現(xiàn)在,讓我們看看在node.js項(xiàng)目中進(jìn)行JWT身份驗(yàn)證的步驟。
步驟1:設(shè)置項(xiàng)目
首先,創(chuàng)建一個新目錄:
mkdir nodejs-jwt-auth cd nodejs-jwt-auth
在終端中運(yùn)行以下命令初始化項(xiàng)目:
npm init -y
接下來,通過以下命令安裝必要的依賴項(xiàng):
npm install express mongoose jsonwebtoken dotenv
上面的命令將安裝:
- express:用于構(gòu)建Web服務(wù)器。
- mongoose:MongoDB的ODM(對象數(shù)據(jù)建模)庫。
- jsonwebtoken:生成和驗(yàn)證JSON Web令牌(JWT)以進(jìn)行身份驗(yàn)證。
- dotenv:從
.env
文件加載環(huán)境變量。
此時,您的package.json
文件應(yīng)該如下所示:
步驟2:獲取MongoDB連接字符串
要獲取MongoDB連接字符串,請查看以下鏈接。
9 Steps to Build a RESTful API with Node.js, MongoDB, and Express
步驟3:創(chuàng)建.env文件
為了保護(hù)MongoDB連接信息,讓我們在根目錄中創(chuàng)建一個名為.env
的新文件。
將以下代碼添加到.env
文件中。
MONGODB_URL=<Your MongoDB Connection String> SECRET_KEY="your_secret_key_here"
將 <Your MongoDB Connection String>
替換為您從MongoDB Atlas獲得的連接字符串。
MONGODB_URL='mongodb+srv://shefali:********@cluster0.sscvg.mongodb.net/nodejs-jwt-auth' SECRET_KEY="ThisIsMySecretKey"
最后,在MONGODB_URL中,我添加了nodejs-jwt-auth
,這是我們的數(shù)據(jù)庫名稱。
步驟4:設(shè)置Express應(yīng)用程序
在根目錄下創(chuàng)建一個名為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}`); });
現(xiàn)在,讓我們通過以下命令運(yùn)行服務(wù)器。
node index.js
輸出如下圖所示:
通過使用命令node index.js
,必須在每次更改文件時重新啟動服務(wù)器。為了避免這種情況,您可以使用以下命令安裝nodemon
。
npm install -g nodemon
現(xiàn)在使用下面的命令運(yùn)行服務(wù)器,它會在每次更改文件時重新啟動服務(wù)器。
nodemon index.js
步驟5:創(chuàng)建用戶模型
在根目錄下創(chuàng)建一個名為“models”的新目錄,并在其中創(chuàng)建一個名為“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);
步驟6:實(shí)現(xiàn)身份驗(yàn)證路由
在根目錄中,創(chuàng)建一個名為“routes”的新目錄,并在其中創(chuàng)建一個名為“auth.js”的文件。
現(xiàn)在,將以下代碼添加到該文件中:
const express = require("express"); const jwt = require("jsonwebtoken"); const User = require("../models/User"); const router = express.Router(); // Signup route router.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 route router.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;
步驟7:使用中間件保護(hù)路由
在根目錄中,創(chuàng)建一個名為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;
代碼是一個中間件函數(shù),用于在應(yīng)用程序中驗(yàn)證JSON Web令牌(JWT)。
步驟8:解碼細(xì)節(jié)
現(xiàn)在要解碼詳細(xì)信息,請修改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 route app.use('/auth', authRouter); //decodeDetails Route app.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處理,用于用戶身份驗(yàn)證。
app.get('/decodeDetails', verifyJWT, (req, res) => { const { username } = req.user; res.json({ username }); });
當(dāng)向/decodeDetails
發(fā)出請求時,verifyJWT中間件驗(yàn)證JWT令牌。
步驟9:測試API
為了測試API,使用了名為Thunder Client的VS Code擴(kuò)展。
注冊
向 http://localhost:3000/auth/signup
發(fā)送一個POST請求,其中包含Headers Content-Type : application/json
和以下JSON主體:
{ "username": "shefali", "password": "12345678" }
在響應(yīng)中,您將看到消息“新用戶注冊成功”。
登錄
向 http://localhost:3000/auth/login
發(fā)送一個POST請求,其中包含Header Content-Type : application/json
和JSON主體,以及您在注冊路由中創(chuàng)建的用戶名和密碼。
{ "username": "shefali", "password": "12345678" }
在響應(yīng)中,您將收到一個令牌。記下這個令牌,因?yàn)樵跍y試decodeDetails路由時需要它。
decodeDetails
向 http://localhost:3000/decodeDetails
發(fā)送一個GET請求,并帶有令牌值的Authorization頭。
在響應(yīng)中,您將獲得用戶名。
您已經(jīng)在Node.js應(yīng)用程序中成功實(shí)現(xiàn)了JWT身份驗(yàn)證。這種方法提供了一種安全有效的方式,來驗(yàn)證Web應(yīng)用程序中的用戶。
以上就是Node.js中JWT實(shí)現(xiàn)身份驗(yàn)證的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于Node.js JWT身份驗(yàn)證的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
我的Node.js學(xué)習(xí)之路(三)--node.js作用、回調(diào)、同步和異步代碼 以及事件循環(huán)
本篇文章主要介紹了node.js的幾個重要的知識點(diǎn):node.js作用、回調(diào)、同步和異步代碼 以及事件循環(huán)2014-07-07Node.js 多線程實(shí)戰(zhàn)小結(jié)
在?Node.js?的世界中,多線程技術(shù)一直是一個受到廣泛關(guān)注的領(lǐng)域,本文主要介紹了Node.js 多線程實(shí)戰(zhàn)小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-01-01NodeJS使用Range請求實(shí)現(xiàn)下載功能的方法示例
本篇使用 NodeJS 的 HTTP 服務(wù)創(chuàng)建客戶端,使用 Range 請求實(shí)現(xiàn)下載功能,本篇使用 NodeJS 的 HTTP 服務(wù)創(chuàng)建客戶端,使用 Range 請求實(shí)現(xiàn)下載功能2018-10-10