Node.js API 使用 JWT(Json Web Token)进行身份验证 - Auth 中间件
大家好,今天我们将在 Node.js 应用程序中使用JWT实现API身份验证。身份验证是每个应用程序中最重要的功能。即使您是初学者,也可以尝试本教程,我们将从零开始。我们还将编写Auth中间件,仅允许经过身份验证的用户访问路由。
在 React 中使用 JWT(Json Web Token)进行身份验证
为了更好地理解,请观看演示视频
源代码
让我们开始编码...
应用程序概述:
方法 | 网址 | 行动 |
---|---|---|
邮政 | /api/用户 | 创建用户 |
邮政 | /api/授权 | 验证用户 |
得到 | /api/用户/我 | 获取已验证用户的详细信息 |
创建 Node.js 应用程序并安装依赖项
$ mkdir node-auth-jwt
$ cd node-auth-jwt
$ npm init --yes
$ npm install express mongoose jsonwebtoken bcrypt joi dotenv
express: Express 是最小且灵活的 Node.js Web 应用程序框架。mongoose
: Mongoose 是 MongoDB 和 Node.js 的对象数据建模(ODM)库
。jsonwebtoken:它是一个表示要在双方之间转移的声明的紧凑 URL。bcrypt
:它是一个密码哈希函数。joi
: Joi 是一种对象模式描述语言和 JavaScript 对象的验证器。dotenv
:它从 .env 文件加载环境变量。
设置 Express Web 服务器
/index.js
require("dotenv").config();
const express = require("express");
const app = express();
app.use(express.json());
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}...`));
配置环境变量
/.env
DB = "mongodb://localhost/node-auth-api/"
JWTPRIVATEKEY = "secretkey"
SALT = 10
配置 MongoDB 数据库
/db.js
const mongoose = require("mongoose");
module.exports = async () => {
try {
const connectionParams = {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
};
await mongoose.connect(process.env.DB, connectionParams);
console.log("connected to database.");
} catch (error) {
console.log("could not connect to database", error);
}
};
在index.js中导入db.js并调用
//...
const connection = require("./db");
const express = require("express");
const app = express();
connection();
app.use(express.json());
//...
创建用户模型
/models/user.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const jwt = require("jsonwebtoken");
const Joi = require("joi");
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
});
userSchema.methods.generateAuthToken = function () {
const token = jwt.sign({ _id: this._id }, process.env.JWTPRIVATEKEY);
return token;
};
const User = mongoose.model("user", userSchema);
const validate = (user) => {
const schema = Joi.object({
name: Joi.string().required(),
email: Joi.string().email().required(),
password: Joi.string().required(),
});
return schema.validate(user);
};
module.exports = { User, validate };
我们所做的:
- 我们创建了包含姓名、电子邮件和密码的用户表。
- 使用JWT,我们生成带有用户 ID 有效负载的令牌。
- 使用Joi,我们将验证数据。
注册路由
/routes/users.js
const { User, validate } = require("../models/user");
const bcrypt = require("bcrypt");
const express = require("express");
const router = express.Router();
router.post("/", async (req, res) => {
try {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
const user = new User(req.body);
const salt = await bcrypt.genSalt(Number(process.env.SALT));
user.password = await bcrypt.hash(user.password, salt);
await user.save();
res.send(user);
} catch (error) {
console.log(error);
res.send("An error occured");
}
});
module.exports = router;
登录路由
/routes/auth.js
const { User } = require("../models/user");
const bcrypt = require("bcrypt");
const Joi = require("joi");
const express = require("express");
const router = express.Router();
router.post("/", async (req, res) => {
try {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
const user = await User.findOne({ email: req.body.email });
if (!user) return res.status(400).send("Invalid email or password");
const validPassword = await bcrypt.compare(
req.body.password,
user.password
);
if (!validPassword)
return res.status(400).send("Invalid email or password");
const token = user.generateAuthToken();
res.send(token);
} catch (error) {
console.log(error);
res.send("An error occured");
}
});
const validate = (user) => {
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().required(),
});
return schema.validate(user);
};
module.exports = router;
身份验证中间件
/middleware/auth.js
const jwt = require("jsonwebtoken");
module.exports = (req, res, next) => {
try {
const token = req.header("x-auth-token");
if (!token) return res.status(403).send("Access denied.");
const decoded = jwt.verify(token, process.env.JWTPRIVATEKEY);
req.user = decoded;
next();
} catch (error) {
res.status(400).send("Invalid token");
}
};
用户获取路线
/routes/users.js
const auth = require("../middleware/auth");
//...
router.get("/me", auth, async (req, res) => {
try {
const user = await User.findById(req.user._id).select("-password -__v");
res.send(user);
} catch (error) {
console.log(error);
res.send("An error occured");
}
});
module.exports = router;
在 Index.js 中导入路由
//...
const users = require("./routes/users");
const auth = require("./routes/auth");
//...
app.use(express.json());
app.use("/api/users", users);
app.use("/api/auth", auth);
//...
就这样!运行服务器并测试 API。如果您发现任何错误或需要改进代码,请在评论中告诉我。希望您有所收获。
谢谢...
文章来源:https://dev.to/mrcyberwolf/node-js-api-authentication-with-jwt-json-web-token-auth-middleware-ggm