Я думаю, что я решил эту проблему в процессе написания, в основном решение выглядит так:
Переместить обработчик статического файла над другим экземпляром use ()
Подтверждение того, что это приемлемый подход, будет оценено, хотя и, возможно, поможет другим в подобном сценарии.
Желаемое поведение
Применить экземпляр use()
ко всем маршрутам, кроме тех, которые обрабатываются:
app.use(express.static("dist"));
Фактическое поведение
use()
применяется ко всем маршрутам, включая те, которые обрабатываются:
app.use(express.static("dist"));
Сценарий
Для защиты доступа к API я использую модель, описанную в этом руководстве Lynda.com:
Node.js: защита API RESTful
В псевдокоде модель по существу состоит из:
- глобальный
use()
экземпляр, который проверяет, был ли отправлен токен jwt
- если токен был отправлен, если верифицирует токен
- устанавливает свойство
req.user
на undefined
, если проверка не удалась или токен не был отправлен
- в противном случае он устанавливает свойство
req.user
для декодированного значения jwt, если проверка прошла успешно
- последующее промежуточное ПО выполняет условное поведение на основе значения
req.user
Эта модель хорошо работает для любых целей.
Однако недавно я добавил некоторые записи в консоли и вижу, что проверка выполняется для обоих:
Вопрос
Как я могу применить проверочный экземпляр use()
ко всем маршрутам, кроме тех, которые обрабатываются app.use(express.static("dist"))
.
Что я пробовал
Мне кажется, я решил эту проблему, переместив раздел 2
кода ниже раздела 1
.
// 01. verification use() called on all requests
app.use((req, res, next) => {
// if jwt authorisation has been sent in headers, verify it
if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'JWT') {
console.log("jwt verification sent, verifying...");
try {
// this is synchronous as it has no callback
req.user = jsonwebtoken.verify(req.headers.authorization.split(' ')[1], 'RESTFULAPIs');
console.log("jwt verified, will return decoded value");
} catch (err) {
req.user = undefined;
console.log("jwt verification failed, user will remain undefined: " + err);
}
// move to the next piece of middleware
next();
}
// if jwt authorisation has not been sent in headers
else {
console.log("jwt verification not sent, leaving user as undefined");
console.log(req.originalUrl);
req.user = undefined;
// move to the next piece of middleware
next();
}
});
// 02. use() for serving static files
app.use(express.static("dist"));
// 03. middleware to check if login has been verified
const api_login_required = (req, res, next) => {
// if token verification was successful and the user property exists
if (req.user) {
// move to the next piece of middleware
next();
}
// otherwise, return unauthorised user message
else {
res.json({ verification: 0 });
}
}
// 04. middleware called in route handlers
app.route("/api/:api_version/users/private_data")
.get(api_login_required, api_users_private_data_get)
.post(api_login_required, api_users_private_data_post);