mongodb - 如何在后端实现基于角色的访问控制
问题描述
我之前创建了一个后端,以便管理人员可以登录以访问管理页面。但是,我的问题是我想实现基于角色的访问控制,因为我希望超级管理员是唯一能够删除用户的人,而普通管理员只允许创建、阅读、更新和删除帖子。我一直无法弄清楚如何做到这一点。如果有人对实现这一点有任何建议,那将非常有帮助。以下代码是我为后端用户注册/登录/注销/令牌所拥有的一切。
用户模型.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema
const UserSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true },
passwordHash: { type: String, required: true },
role: {type: String, enum:["admin", "superadmin"]},
},
{timestamps: true}
);
module.exports={
User: mongoose.model("users", UserSchema),
}
用户路由器.js
const router = require("express").Router();
const {User} = require("../models/userModel");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
// register
router.get("/", (req, res) => {
User.find().exec((err, users) =>{
if(err) return res.status(400).json({ success: false, err });
return res.status(200).json({ success: true, users: users });
});
});
router.delete("/delete/:id", (req, res) => {
User.findByIdAndRemove(req.params.id).exec((err, deleteItem) => {
if(err){
res.send(err);
}
return res.json(deleteItem);
})
})
router.post("/", async (req, res) => {
try {
const { name, email, password, passwordVerify } = req.body;
// validation
if (!name || !email || !password || !passwordVerify)
return res
.status(400)
.json({ errorMessage: "Please enter all required fields." });
if (password.length < 6)
return res.status(400).json({
errorMessage: "Please enter a password of at least 6 characters.",
});
if (password !== passwordVerify)
return res.status(400).json({
errorMessage: "Please enter the same password twice.",
});
const existingUser = await User.findOne({ email });
if (existingUser)
return res.status(400).json({
errorMessage: "An account with this email already exists.",
});
// hash the password
const salt = await bcrypt.genSalt();
const passwordHash = await bcrypt.hash(password, salt);
// save a new user account to the db
const newUser = new User({
name,
email,
passwordHash,
});
const savedUser = await newUser.save();
// sign the token
const token = jwt.sign(
{
user: savedUser._id,
},
process.env.JWT_SECRET
);
// send the token in a HTTP-only cookie
res
.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
})
.send();
} catch (err) {
console.error(err);
res.status(500).send();
}
});
// log in
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
// validate
if (!email || !password)
return res
.status(400)
.json({ errorMessage: "Please enter all required fields." });
const existingUser = await User.findOne({ email });
if (!existingUser)
return res.status(401).json({ errorMessage: "Wrong email or password." });
const passwordCorrect = await bcrypt.compare(
password,
existingUser.passwordHash
);
if (!passwordCorrect)
return res.status(401).json({ errorMessage: "Wrong email or password." });
// const sessUser = { id: user.id, name: user.name, email: user.email };
// req.session.user = sessUser; //Auto saves session data in mongo store
// res.json({ msg: "Logged In Successfully", sessUser }); //sends cookie with sessionId automatically in response
// sign the token
const token = jwt.sign(
{
user: existingUser._id,
},
process.env.JWT_SECRET
);
// send the token in a HTTP-only cookie
res
.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
})
.send();
} catch (err) {
console.error(err);
res.status(500).send();
}
});
router.get("/logout", (req, res) => {
res
.cookie("token", "", {
httpOnly: true,
expires: new Date(0),
secure: true,
sameSite: "none",
})
.send();
});
router.get("/loggedIn", (req, res) => {
try {
const token = req.cookies.token;
if (!token) return res.json(false);
jwt.verify(token, process.env.JWT_SECRET);
res.send(true);
} catch (err) {
res.json(false);
}
});
module.exports = router;
auth.js
const jwt = require("jsonwebtoken");
function auth(req, res, next) {
try {
const token = req.cookies.token;
if (!token) return res.status(401).json({ errorMessage: "Unauthorized" });
const verified = jwt.verify(token, process.env.JWT_SECRET, {expiresIn: "7d"});
req.user = verified.user;
next();
} catch (err) {
console.error(err);
res.status(401).json({ errorMessage: "Unauthorized" });
}
}
module.exports = auth;
解决方案
推荐阅读
- amazon-web-services - 如何使用第三方应用程序登录亚马逊 mws
- node.js - 如何使用 Nodejs 在 IBM watson 助手中添加对话节点的更新多个响应
- java - 在 SpringBoot 中创建一个可重用的 Reader 类
- xml - 从特定的 excel 范围创建 XML
- vaadin - Vaadin Flow Grid 没有高度
- android - 如何在最新的 Android 工作室(即 v3.1.1)中分析视图层次结构
- sql - 将具有不同数据的两行分成两个不同的列
- tcp - TCP RENO MSS、发送方窗口、阈值和接收方窗口
- c++ - Qt 如何在 QRect 上设置焦点
- php - 用于在新选项卡中打开多个链接但仅在一个选项卡中打开多个链接的 PHP 或 jq 代码