Javascript 如何在Express中识别用户是否为管理员?
你好 我正在尝试建立一个登录系统,客户端和管理员都可以登录。如果用户是管理员,则他/她将被重定向到管理面板;如果不是,则用户将被重定向到webshop的主页。我对身份验证的逻辑有点纠结。我正在尝试识别用户是否已登录。如果/she为,则我通过检查“isAdmin”是否为真来验证用户角色。我通过在数据库中查找isAdmin状态来查找用户。我使用jwt令牌来获取用户的状态 身份验证:Javascript 如何在Express中识别用户是否为管理员?,javascript,node.js,express,jwt,Javascript,Node.js,Express,Jwt,你好 我正在尝试建立一个登录系统,客户端和管理员都可以登录。如果用户是管理员,则他/她将被重定向到管理面板;如果不是,则用户将被重定向到webshop的主页。我对身份验证的逻辑有点纠结。我正在尝试识别用户是否已登录。如果/she为,则我通过检查“isAdmin”是否为真来验证用户角色。我通过在数据库中查找isAdmin状态来查找用户。我使用jwt令牌来获取用户的状态 身份验证: const { verify } = require("jsonwebtoken"); const
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",
});
});
代码基于我的评论吼叫你的问题
const { verify } = require("jsonwebtoken");
const userModel = require("../model/userModel");
const isAuth = (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send("Access denied");
try {
const verified = verify(token, process.env.SECRET);
req.user = verified;
console.log('Am i admin?', req.user.isAdmin);
next();
} catch (err) {
res.status(400).send("Invalid token");
}
};
const isAdmin = async (req, res, next) => {
// no need to verify token again
// the `req.user.isAdmin` is already available from isAuth
// also no need to query a database, we have all the info we need from the token
if (!req.user.isAdmin)
return res.status(401).send({ msg: "Not an admin, sorry" });
next();
};
router.post("/login", async (req, res) => {
const user = findUserSomehow();
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,
});
});
// notice the order of middlewares, isAuth first
router.get("/adminPanel", isAuth, isAdmin, (req, res) => {
res.json({
title: "ADMIN PANEL",
});
});
那么,到底是什么没有按预期工作?@rveerd确定管理员您不需要同时使用
isAdmin
和isAuth
中间件。实际上,isAuth就足够了,因为您可以在isAuth中间件中检查用户是否是admin,令牌中包含该信息。因此,请尝试从路由和isAuth try console.log中删除isAdmin('Am i admin?:',verified.isAdmin);还有这个let user=await userModel.findOne({isAdmin})代码>不太可能按您想要的方式工作。这个{isAdmin}
是{isAdmin:isAdmin}
的快捷方式。这里的问题是isAdmin是一个函数const isAdmin=async(req,res,next)=>{
您是想使用{isAdmin:verified.isAdmin}
?尽管这也不起作用,因为您只会找到第一个用户,而该用户不一定是您认为的管理员。您应该像这样使用_idlet user=wait userModel.findOneById(已验证。_id);
但正如我所说,您根本不需要isAdmin中间件。非常感谢。还有一个问题,我将如何注销用户?通过删除带有auth令牌的标头?不客气。我对jwt令牌不太熟悉,所以很难说。但这肯定是一种方法。这取决于您在cli上存储jwt令牌的位置/方式请接受我的回答。