Я посмотрел его в Google, но ничего не нашел об этой теме c - возможно, мой поисковый запрос был неправильным. Я надеюсь, что вы можете ответить на этот вопрос.
Я использую аутентификацию на основе JWT для моего REST API, который написан на express. Чтобы гарантировать, что пользователь без прав администратора не сможет ничего сделать, я добавил два промежуточных программного обеспечения на свой маршрутизатор. Токен был проверен внутри этих промежуточных программ, если API получил вызов и проверил, разрешено ли пользователю продолжить. У пользователя может быть несколько ролей, а также роль администратора.
Теперь я перейду к своему коду. Я просто хочу поделиться необходимыми частями своего кода. Если есть какие-либо вопросы или я что-то пропустил, пожалуйста, скажите мне.
Мой index.ts
выглядит следующим образом:
import express from "express;
...
import { myRouter } from "./api/router/myRouter";
const app = express();
app.use("/api", myRouter);
app.listen(7000);
...
В моем myRouter.ts
я использую два промежуточных программного обеспечения, как упомянуто выше:
import authJwt from "./auth/middleware/authJwt.middleware";
export const myRouter = express.Router();
myRouter.use(authJwt.verifyToken);
myRouter.use(authJwt.isAdmin);
...
В моем authJwt.middleware.ts
я определил методы:
function verifyToken(req: Request, res: Response, next: NextFunction) {
let token = req.headers["x-access-token"] as string;
if (!token) {
return res.status(403).send({
message: "No token provided!"
});
}
const secret = process.env.JWT_SECRET as string;
jwt.verify(token, secret, (err, decoded: any) => {
if (err) {
return res.status(401).send({
message: "Unauthorized!"
});
}
req.body.userId = decoded.id; //This is the part related to my question
next();
});
}
function isAdmin(req: Request, res: Response, next: NextFunction) {
UserService.getRoles(req.body.userId).then(roles => {
for (let i = 0; i < roles.length; i++) {
if (roles[i].name === "admin") {
next();
return;
}
}
return res.status(403).send({
message: "Require Admin Role!"
});
});
}
const authJwt = {
verifyToken: verifyToken,
isAdmin: isAdmin
};
export default authJwt;
В порядке промежуточного программного обеспечения мой verifyToken
меняет тело запроса и добавляет id
, хранящийся в JWT до того как userId
. Следующее промежуточное программное обеспечение isAdmin
будет использовать это измененное тело запроса и получит userId
для получения ролей для пользователя. Роли пользователя предоставляются UserService
. Мой UserService
позвонит в мою базу данных, чтобы получить информацию о пользователе и его ролях.
Весь приведенный выше код работает!
Мой вопрос таков: чтобы уменьшить трафик c в моей базе данных, я мог бы закодировать дырочного пользователя с его ролями внутри JWT. Поэтому, когда я проверяю и декодирую токен, я получу свой полный пользовательский объект со всеми его ролями. И этот пользовательский объект я мог бы добавить в тело запроса, а не просто его идентификатор. Поэтому больше не нужно было бы вызывать мою базу данных, чтобы получить роли пользователей.
НО это безопасный способ? Или кто-то может внедрить другой объект пользователя в тело запроса после того, как первое промежуточное ПО (verifyToken
) изменило тело запроса и вызвать функцию express next()
, чтобы дать своему пользователю дополнительные роли?
Поскольку каждый Когда вызывается конечная точка моего API, я сделаю дополнительные запросы к базе данных для извлечения пользовательского объекта.
Какова лучшая практика здесь?