#node.js #express #jwt
#node.js #экспресс #jwt
Вопрос:
Допустим, у меня есть 10 маршрутов, и каждый маршрут доступен только для определенного типа пользователей. Когда пользователь входит в систему, генерируется токен.Эти пользовательские токены генерируются с их _id
и секретным токеном, который хранится в .env
файле.
Обычно проверка токена для каждого типа пользователя выполняется с помощью отдельных функций, поскольку у разных типов пользователей разные секреты токена. Например, возможно, секрет токена user1 TOKEN_SECRET_USER2 = 6ygfewf6hj
и, возможно, токен user2 TOKEN_SECRET_USER1 = 87uhjkaf89
.
И когда какой-либо запрос отправляется на маршрут, проверяется токен пользователя, чтобы узнать, может ли пользователь получить доступ к этому маршруту или нет.
Вот два примера маршрута, доступных для разных типов пользователей,
// Route accessible to user type 1
router.get("/foo", verifyTokenUSER1, async (req, res) => {
// All the good stuff
});
// Route accessible to user type 2
router.post("/bar", verifyTokenUSER2, async (req, res) => {
// All the good stuff
});
Вот какой-то метод проверки модуля выглядит следующим образом,
// Verification for user 1
const verifyTokenUSER1 = (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send();
try {
jwt.verify(token, process.env.TOKEN_SECRET_USER1);
next();
} catch (err) {
res.status(401).send();
}
};
// Verification for user 2
const verifyTokenUSER2 = (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send();
try {
jwt.verify(token, process.env.TOKEN_SECRET_USER2);
next();
} catch (err) {
res.status(401).send();
}
};
Как вы можете видеть, в приведенных выше методах есть только одно изменение, которое является секретом токена доступа для типов пользователей.
Я хотел бы проверить их, используя 1 (одну) единственную функцию, если это возможно. Но я не могу передать какое-либо значение в качестве параметра методам проверки. Итак, как я могу устранить дублирование здесь?
Ответ №1:
На самом деле вы можете передать параметр методу проверки, если используете bind
(mdn):
// Route accessible to user type 1
router.get("/foo", verifyToken.bind(null, process.env.TOKEN_SECRET_USER1), async (req, res) => {
// All the good stuff
});
// Route accessible to user type 2
router.post("/bar", verifyToken.bind(null, process.env.TOKEN_SECRET_USER2), async (req, res) => {
// All the good stuff
});
bind
метод функции здесь получает 2 параметра: во-первых, this
контекст для функции, а во-вторых, первый аргумент. Он возвращает новую функцию, которая получит предоставленный токен в качестве первого аргумента и получит req, res, next
в качестве следующих аргументов.
const verifyToken = (tokenSecret, req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send();
try {
jwt.verify(token, tokenSecret);
next();
} catch (err) {
res.status(401).send();
}
};
Другим эквивалентным способом сделать это является создание метода проверки «factory», который возвращает функцию проверки, которая имеет замыкание (mdn) на токене:
// Route accessible to user type 1
router.get("/foo", getTokenVerifier(process.env.TOKEN_SECRET_USER1), async (req, res) => {
// All the good stuff
});
// Route accessible to user type 2
router.post("/bar", getTokenVerifier(process.env.TOKEN_SECRET_USER2), async (req, res) => {
// All the good stuff
});
// this function returns a new function, with a closure on the provided tokenSecret
const getTokenVerifier = (tokenSecret) => {
return (req, res, next) => {
const token = req.header("auth-token");
if (!token) return res.status(401).send();
try {
jwt.verify(token, tokenSecret);
next();
} catch (err) {
res.status(401).send();
}
}
}