при получение всех пользоветелей появляеться ошибка что нет доступа
При авторизации мы получаем токен, который вставляем в users, и после если ты admin то тебе выводиться список пользователей, а если ты обычный user то у тебя нет доступа. Прикол в том, что ни user ни admin не могут получить данные. Использую mysql базу данных, стырила все с видео урока, но там используют mongodb. Помогите пожалуйста.Пробовала передавать вручную данные в бд через исомнюю, но не помогло.
rolemiddleware.js
const jwt = require('jsonwebtoken');
const { secret } = require('../config');
module.exports = function (roles) {
return function (req, res, next) {
if (req.method === "OPTIONS") {
next();
}
try {
const token = req.headers.authorization.split(' ')[1];
if (!token) {
return res.status(403).json({ message: "Пользователь не авторизован" });
}
const decodedToken = jwt.verify(token, secret);
const userRoles = decodedToken.roles || [];
let hasRole = false;
userRoles.forEach(role => {
if (roles.includes(role)) {
hasRole = true;
}
});
if (!hasRole) {
return res.status(403).json({ message: "У вас нет доступа" });
}
next();
} catch (e) {
console.log(e);
return res.status(403).json({ message: "Пользователь не авторизован" });
}
};
};
модель юзера
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
return sequelize.define("User", {
userName:{
type: Sequelize.STRING(100),
},
password:{
type: Sequelize.STRING(255),
},
roles: [{type: Sequelize.STRING, ref: 'Role'}]
}, {
timestamps: false,
tableName: 'user'
});
}
модель роли
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
return sequelize.define("Role", {
value:{
type: Sequelize.STRING(100),
unique: true,
defaultValue: 'USER'
},
}, {
timestamps: false
});
}
authcontroller. соединение с бд есть
const generateAccessToken = (id, roles) => {
const payload = {
id, roles
}
return jwt.sign(payload, secret, {expiresIn: "124h"})
}
async getUsers(req, res) {
try {
const connection = await mysql.createConnection({
host:
user:
password:
database:
});
const [rows, fields] = await connection.execute('SELECT * FROM user');
const users = rows.map(row => ({
id: row.id,
userName: row.userName,
email: row.email,
role: row.role,
// т.д - перечислите все поля базы данных
}));
return res.json(users);
} catch (error) {
console.error(error);
res.status(400).json({ message: 'Ошибка при получении пользователей' });
}
}
authRouter
const controllerDo = require('./Controllers/doController')
const router = new Router()
const {check} = require('express-validator')
const authMiddleware = require('./middleware/authMiddleware')
const roleMiddleware = require('./middleware/roleMiddleware')
router.post('/registration', [
check('userName', "Имя пользователя не может быть пустым").notEmpty(),
check('role', "Имя пользователя не может быть пустым").notEmpty(),
check('password', "Пароль должен быть от 4 до 10 символов").isLength({min: 4, max:10})
], controllerAuth.registration)
router.post('/login', controllerAuth.login)
router.get('/users', roleMiddleware(["ADMIN"]), controllerAuth.getUsers)
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"express": "^4.18.2",
"express-validator": "^7.0.1",
"jsonwebtoken": "^9.0.2",
"mysql2": "^3.6.5",
"nodemon": "^3.0.2",
"sequelize": "^6.35.1"
}
}
registr
async registration(req, res) {
try {
const errors = validationResult(req)
if(!errors.isEmpty()) {
return res.status(400).json({message: "Ошибка при регистрации", errors})
}
const { userName, password } = req.body;
const connection = await mysql.createConnection({
...
});
const [rows, fields] = await connection.execute(
'SELECT * FROM user WHERE userName = ?',
[userName]
);
if (rows.length) {
return res.status(400).json({ message: 'Такой пользователь существует' });
}
const hashPassword = bcrypt.hashSync(password, 7);
const userRole = 'USER';
const [results, resultFields] = await connection.execute('INSERT INTO user (userName, password, role) VALUES (?, ?, ?)',
[userName, hashPassword, userRole]
);
return res.json({ message: 'Пользователь успешно зарегестрирован' });
} catch (error) {
console.log(error)
res.status(400).json({message: 'Регистрация не успешна'})
}
}
login
async login(req, res) {
try {
const { userName, password } = req.body;
const connection = await mysql.createConnection
const [rows, fields] = await connection.execute(
'SELECT * FROM user WHERE userName = ?',
[userName]
);
if (!rows.length) {
return res
.status(400)
.json({ message: `Пользователь ${userName} не найден` });
}
const user = rows[0];
const validPassword = bcrypt.compareSync(password, user.password);
if (!validPassword) {
return res.status(400).json({ message: 'Неверный пароль' });
}
const token = generateAccessToken(user._id, user.userRole)
return res.json({token})
// return res.json({ token });
} catch (error) {
console.error(error);
res.status(400).json({ message: 'Ошибка при входе' });
}
}
Ответы (1 шт):
В файле rolemiddleware.js условие if (roles.includes(role)) возвращает false даже в том случае, когда роль пользователя сходится с нужной ролью. Должно сработать :)
-rolemiddleware.js
const jwt = require('jsonwebtoken');
const { secret } = require('../config');
module.exports = function(roles) {
return function(req, res, next) {
if (req.method === "OPTIONS") {
next();
}
try {
const token = req.headers.authorization.split(' ')[1];
if (!token) {
return res.status(403).json({ message: "Пользователь не авторизован" });
}
const decodedToken = jwt.verify(token, secret);
const userRoles = decodedToken.roles || [];
let hasRole = false;
userRoles.forEach(userRole => {
roles.forEach(role => {
if (userRole == role) {
hasRole = true;
}
})
})
if (!hasRole) {
return res.status(403).json({ message: "У вас нет доступа" });
}
next();
} catch (e) {
console.log(e);
return res.status(403).json({ message: "Пользователь не авторизован" });
}
};
};
