【发布时间】:2021-03-13 09:27:46
【问题描述】:
早安,
我正在尝试创建一个客户端和管理员都可以登录的登录系统。如果用户是管理员,那么他/她将被重定向到管理面板,如果不是,那么用户将被重定向到主页网上商店的页面。我在身份验证的逻辑上有点挣扎。我正在尝试确定用户是否已登录。如果/她是,那么我通过检查“isAdmin”是真还是假来验证用户角色。我通过查找 isAdmin 状态在数据库中查找用户来做到这一点。我正在使用 jwt 令牌来获取用户的状态。
身份验证:
const { verify } = require("jsonwebtoken");
const userModel = require("../model/userModel");
// const isAuth = req => {
// const authorization = req.headers["authorization"];
// if (!authorization) throw new Error("You need to login");
// const token = authorization.split(" ")[1];
// const { userId } = verify(token, process.env.ACCESS_TOKEN_SECRET);
// return userId;
// };
const isAuth = (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send("Access denied");
//verifying the token then sending the id back of the user
try {
const verified = verify(token, process.env.SECRET);
req.user = verified;
next();
} catch (err) {
res.status(400).send("Invalid");
}
};
//isAdmin
const isAdmin = async (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send("No User");
try {
const verified = verify(token, process.env.SECRET);
req.user = verified;
let user = await userModel.findOne({ isAdmin });
if (req.user && user.isAdmin === true) {
return next();
}
} catch (err) {
return res.status(401).send({ msg: "Admin token is not valid" });
}
};
//check user
// const checkUser = (req, res, next) => {
// //get token from cookies
// const token = req.cookies.jwt;
// //check if token exists
// if (token) {
// verify(token, process.env.SECRET, async (err, decode) => {
// if (err) {
// console.log(err.message);
// next();
// res.locals.user = null;
// } else {
// console.log(decode);
// next();
// let user = await userModel.findOne(decode.isAdmin);
// res.local.user = user;
// next();
// }
// });
// } else {
// }
// };
module.exports = {
isAuth,
isAdmin,
};
路线:
router.post("/login", async (req, res) => {
const user = await User.findOne({ email: req.body.email });
if (!user) res.send({ error: "User does not exists" });
const validPass = await compare(req.body.password, user.password);
if (!validPass) {
return res.json({ error: "email or password is incorrect" });
}
const token = sign(
{ _id: user._id, isAdmin: user.isAdmin },
process.env.SECRET,
{
expiresIn: "24h",
},
);
res.header("auth-token", token).send({
token,
email: req.body.email,
id: user._id,
});
});
router.get("/adminPanel", isAdmin, isAuth, (req, res) => {
res.json({
title: "ADMIN PANEL",
});
});
【问题讨论】:
-
那么究竟是什么没有按预期工作?
-
@rveerd 识别管理员
-
您不需要同时使用
isAdmin和isAuth中间件。实际上 isAuth 就足够了,因为您可以在 isAuth 中间件中检查用户是否是管理员,令牌具有信息。所以尝试从路由中删除 isAdmin 并在 isAuth 中尝试 console.log('Am i admin? :', verify.isAdmin); -
另外,这个
let user = await userModel.findOne({ isAdmin });不太可能按照您想要的方式工作。这个{ isAdmin }是{ isAdmin: isAdmin }的快捷方式,这里的问题是isAdmin 是一个函数const isAdmin = async (req, res, next) => {你的意思是使用{ isAdmin: verified.isAdmin }吗?尽管即使这样也行不通,因为您只会找到第一个管理员用户,不一定是您认为的用户。你应该使用 _id 来代替let user = await userModel.findOneById(verified._id);但是我说你根本不需要 isAdmin 中间件。
标签: javascript node.js express jwt