每当在路由中使用checkAdmin中间件时,我都会遇到req.user为空的问题
因此,我正在尝试制作此中间件,以检查用户的角色是否为ADMIN,从而允许他创建新用户,但失败了,并且当我从路由中删除中间件时,系统运行正常并保存了用户(ofc检查是否为ADMIN)
这是我的路线文件:
const express = require('express');
const UserController = require('../controllers/user');
const { verificaToken, verificaAdminRol } = require('../middlewares/autenticacion');
const api = express.Router();
api.get('/home', UserController.home);
api.post('/login', UserController.loginUser);
api.post('/save', [verificaAdminRol, verificaToken], UserController.saveUser);
api.get('/listar/:id', verificaToken, UserController.getUsuario);
api.get('/listar', verificaToken, UserController.getAllUsers);
api.put('/actualizar/:id', verificaToken, UserController.actualizarUsuario);
module.exports = api;
这是我的控制器文件:
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const _ = require('underscore');
//Importar modelo
const User = require('../models/user');
function home(req, res) {
res.json({ ok: true, msg: "home de usuarios" });
}
function saveUser(req, res) {
//Recibimos los datos enviados
let body = req.body;
//Se crea un nuevo Objeto Usuario con los datos recibidos
let user = new User({
name: body.name,
surname: body.surname,
nick: body.nick,
email: body.email,
//Encriptación del password
password: bcrypt.hashSync(body.password, 10),
role: body.role
});
//Se guarda el user en la BD
user.save((err, usuarioDB) => {
if (err) {
return res.status(400).json({
ok: false,
msg: `Error ${err}`
})
}
return res.send({
ok: true,
user: usuarioDB,
msg: "Usuario creado exitosamente."
})
});
}
function loginUser(req, res) {
let body = req.body;
User.findOne({ email: body.email }, (err, usuarioDB) => {
if (err) {
return res.status(500).json({ ok: false, msg: `Error ${err}` });
}
if (!usuarioDB) {
return res.status(400).json({ ok: false, msg: "Email incorrecto" });
}
if (!bcrypt.compareSync(body.password, usuarioDB.password)) {
return res.status(400).json({ ok: false, msg: "Password incorrecto" });
}
//creando el token
let token = jwt.sign({
user: usuarioDB
}, process.env.SEED, { expiresIn: process.env.CADUCIDAD_TOKEN });
if (usuarioDB) {
return res.send({
ok: true,
user: usuarioDB,
token
})
}
});
}
module.exports = {
home,
saveUser,
loginUser
}
这是我的中间件文件:
const jwt = require('jsonwebtoken');
//==============================================
//Verificar que el token sea válido
//==============================================
let verificaToken = (req, res, next) => {
//1- Leer el token que viene en el header llamado 'token'
let token = req.get('token');
//token, semilla, callback(error, objeto desencriptado)
jwt.verify(token, process.env.SEED, (err, decoded) => {
if (err) {
return res.status(401).json({
ok: false,
err: {
message: "Token no válido."
}
});
}
req.user = decoded.user;
next();
});
};
//====================================================================
//Verificar que el usuario sea ADMIN para crear, actualizar y eliminar
//====================================================================
//this is the one with the problem
let verificaAdminRol = (req, res, next) => {
let usuario = req.user;
if (usuario.role === 'ADMIN') {
next(); //puedo continuar, pasó la verificación
} else {
return res.json({
ok: false,
message: "Debe tener privilegios de ADMIN para poder realizar esta operación"
});
}
};
module.exports = {
verificaToken,
verificaAdminRol
}
最后,这是我尝试使用'verificaAdminRol'中间件创建新用户时遇到的错误:
TypeError: Cannot read property 'role' of undefined
at verificaAdminRol (C:\Users\gorydev\Documents\Development\udemy\red-social\middlewares\autenticacion.js:35:17)
at Layer.handle [as handle_request] (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:317:13)
at C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\express\lib\router\index.js:275:10)
at jsonParser (C:\Users\gorydev\Documents\Development\udemy\red-social\node_modules\body-parser\lib\types\json.js:101:7)
我的项目结构是:
/project
->/controllers
---->user.js
->/middlewares
---->autenticacion.js
->/models
---->user.js
->/routes
---->user.js
答案 0 :(得分:0)
我相信您的中间件故障。中间件verificaToken
设置了req.user
的值,但是它在访问该值的verificaAdminRol
之后运行。看到这里:
api.post('/save', [verificaAdminRol, verificaToken], UserController.saveUser);
需要为:
api.post('/save', [verificaToken, verificaAdminRol], UserController.saveUser);
让我知道是否可行。
编辑:边注。最佳实践表明,您不应直接写入req
对象。 Express提供req.locals
,以根据每个请求在中间件和路由之间传递值。只是一个建议。