介绍
身份验证是 Web 应用程序的关键部分,可确保只有授权用户才能访问某些资源。最安全且可扩展的身份验证方法之一是JWT(JSON Web Token)身份验证。在本指南中,我们将使用Passport.js(一种流行的 Node.js 身份验证中间件) 实现 JWT 身份验证。
什么是 JWT?
JSON Web Token (JWT)是一种紧凑、URL 安全的令牌格式,用于以 JSON 对象的形式在各方之间安全地传输信息。它由三部分组成:
标题——包含有关令牌的元数据(例如,使用的算法)。
有效负载——包含与用户相关的数据(例如用户 ID)。
签名——确保令牌的完整性和真实性。
为什么使用 Passport.js?
Passport.js是一个简化 Node.js 应用程序中身份验证的中间件。它支持多种策略,包括JWT 身份验证。
项目设置
步骤 1:初始化 Node.js 项目
mkdir jwt-auth-example
cd jwt-auth-example
npm init -y
第 2 步:安装所需的依赖项
npm install express passport passport-jwt jsonwebtoken dotenv bcryptjs mongoose
express– Node.js 的 Web 框架
passport– 身份验证中间件
passport-jwt– Passport.js 的 JWT 策略
jsonwebtoken– 生成 JWT 的库
dotenv– 加载环境变量
bcryptjs– 安全地散列密码
mongoose– MongoDB ORM
构建身份验证系统
步骤 3:创建文件夹结构
jwt-auth-example
│── config/
│ ├── passport.js
│── models/
│ ├── User.js
│── routes/
│ ├── auth.js
│── server.js
│── .env
│── package.json
步骤 4:设置 MongoDB 和用户模型
连接到 MongoDB
创建一个.env文件并添加您的MongoDB 连接字符串:
MONGO_URI=mongodb://localhost:27017/jwt-auth
JWT_SECRET=your_secret_key
创建User.js模型(models/文件夹内)
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
module.exports = mongoose.model("User", UserSchema);
步骤 5:配置 Passport.js 进行 JWT 身份验证
创建passport.js(config/文件夹内)
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const User = require("../models/User");
const dotenv = require("dotenv");
dotenv.config();
const opts = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET,
};
module.exports = (passport) => {
passport.use(
new JwtStrategy(opts, async (jwt_payload, done) => {
try {
const user = await User.findById(jwt_payload.id);
if (user) {
return done(null, user);
}
return done(null, false);
} catch (err) {
console.error(err);
}
})
);
};
步骤 6:创建身份验证路由
创建auth.js(routes/文件夹内)
const express = require("express");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const passport = require("passport");
const User = require("../models/User");
const dotenv = require("dotenv");
dotenv.config();
const router = express.Router();
// Register Route
router.post("/register", async (req, res) => {
const { username, email, password } = req.body;
try {
let user = await User.findOne({ email });
if (user) return res.status(400).json({ msg: "User already exists" });
const hashedPassword = await bcrypt.hash(password, 10);
user = new User({ username, email, password: hashedPassword });
await user.save();
res.json({ msg: "User registered successfully" });
} catch (err) {
res.status(500).json({ msg: "Server error" });
}
});
// Login Route
router.post("/login", async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user) return res.status(400).json({ msg: "User not found" });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ msg: "Invalid credentials" });
const payload = { id: user.id, username: user.username };
jwt.sign(
payload,
process.env.JWT_SECRET,
{ expiresIn: "1h" },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
res.status(500).json({ msg: "Server error" });
}
});
// Protected Route
router.get(
"/profile",
passport.authenticate("jwt", { session: false }),
(req, res) => {
res.json({ user: req.user });
}
);
module.exports = router;
步骤 7:设置服务器
创造server.js
const express = require("express");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const passport = require("passport");
const authRoutes = require("./routes/auth");
dotenv.config();
const app = express();
app.use(express.json());
mongoose
.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("MongoDB connected"))
.catch((err) => console.error(err));
require("./config/passport")(passport);
app.use(passport.initialize());
app.use("/api/auth", authRoutes);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
测试身份验证系统
启动服务器
node server.js
注册用户
curl -X POST http://localhost:5000/api/auth/register -H "Content-Type: application/json" -d '{"username": "hardik", "email": "hardik@example.com", "password": "123456"}'
登录获取令牌
curl -X POST http://localhost:5000/api/auth/login -H "Content-Type: application/json" -d '{"email": "hardik@example.com", "password": "123456"}'
复制收到的JWT 令牌。
访问受保护的路线
curl -X GET http://localhost:5000/api/auth/profile -H "Authorization: Bearer YOUR_JWT_TOKEN"
结论
在本指南中,我们在 Node.js 应用程序中使用Passport.js实现了JWT 身份验证。我们涵盖了: ✅ 用户注册和密码哈希 ✅ 使用 JWT 生成进行用户登录 ✅ 使用 Passport.js 保护路由
这种方法可确保现代 Web 应用程序中的安全身份验证。🚀

