У меня проблема с пониманием синтаксиса nodejs. Я пытаюсь настроить сообщения об ошибках паспорта и следую этому коду:
router.get('/', (req, res, next) => {
passport.authenticate('jwt', {session: false}, function(err, user, info) {
//do some stuff here
//if error, return some stuff
res.json({...})
})(req, res, next)
}
Но в синтаксисе в руководстве, которому я следую, router.route был создан следующим образом:
router.route('/')
.get(passport.authenticate('jwt', {session: false}, (err, user, info) => {
//res cannot be found here
res.json({...})
}), UsersController.index);
Поскольку у меня был этот тип синтаксиса, в котором задействовано промежуточное программное обеспечение паспорта и контроллер, res.json () становится неопределенным ... как мне передать параметры res, req и далее в этом синтаксисе?





Хорошо, поэтому В основном Я бы не стал настраивать сообщение об ошибке в обратном вызове аутентификации, как вы хотите. Во-первых, вы будете повторяться при каждом вызове аутентификации, если вы это сделаете, а во-вторых, это просто не проблема этого промежуточного программного обеспечения.
Однако я стараюсь централизовать обработку ошибок и обмен сообщениями, что требует более длительного обсуждения.
Если вы действительно хотите это сделать, вам нужно убедиться, что req, res, next находится в области видимости, например:
app.route('/login')
.get(function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
err.message = 'Incorrect username or password';
return next(err);
}
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
Хорошо, что касается централизации обработки ошибок, подход, который я обычно использую, заключается в создании пользовательских классов ошибок, которые я могу создавать по мере необходимости, а затем обрабатывать в промежуточном программном обеспечении обработки ошибок. Это можно применить к аутентификации так же легко, как и ко всему остальному, и вы можете создавать их постепенно по мере роста проекта, так что это не слишком сложно. Например, начиная с пользовательского FailedLoginError, я мог бы сделать что-то вроде этого (в синтаксисе ES6 это не сложнее в старом синтаксисе JS):
// ./lib/errors/failed-login-error.js
class FailedLoginError extends Error {
// You could set the message here if you wanted rather than letting the calling code set it
constructor(error, userMessage) {
super(error.message);
this.name = this.constructor.name;
this.previousError = error;
this.statusCode = 401;
this.userMessage = userMessage || 'You provided an incorrect username or password';
Error.captureStackTrace(this, this.constructor);
}
}
Затем я бы создал специальное промежуточное программное обеспечение, которое обертывает настройку Passport, чтобы мне не приходилось помнить об использовании его каждый раз.
// ./lib/middleware/authenticate.js
// Similar to the example above, we have an error that has a 500 status
const ServerError = require('../errors/internal-server-error');
const FailedLoginError = require('../errors/failed-login-error');
module.exports = (req, res, next) => {
passport.authenticate('jwt', { session: false }, (err, user, info) => {
// an exception happened trying to do the login
if (err) return next(new ServerError(err));
// user was not correct. Add more info to the error message if you want, like maybe the Username was incorrect or the Token was expired or whatever.
if (!user) return next(new FailedLoginError(err));
// we get here and the user logged in right
req.logIn(user, (e) => {
if (e) return next(ServerError(e));
return res.redirect('/users/' + user.username); // or whatever the right thing is here
});
});
});
Итак, с этой настройкой вы теперь можете настроить промежуточное программное обеспечение для обработки ошибок, которое использует ваши пользовательские ошибки:
// ./lib/middleware/error-handler.js
module.exports = (err, req, res, next) {
// normalize the possibly missing status and userMessages
err.statusCode = err.statusCode || 500;
err.userMessage = err.userMessage || 'Something went wrong.';
// always log something; use something other than console.error if you like
// note here we're logging the real error message.
console.error(`${req.method} ${req.url} - ${err.statusCode} - ${err.message}`);
// next, give the user something you don't mind them seeing
res.status(err.statusCode).send(err.userMessage);
};
Теперь, чтобы собрать все это вместе, код вашего приложения упростится примерно до следующего:
const errorHandler = require('./lib/middleware/error-handler');
const authenticate = require('./lib/middleware/authenticate');
// other requires as needed.
app.use(errorHandler);
app.route('/login')
.all(authenticate)
.get((req, res, next) => {
// whatever you want to do here, it's already got a user and so on.
});
Некоторое время назад я собрал библиотеку, которая использует этот шаблон и создает кучу общих классов ошибок HTTP. Вероятно, это будет обновление, но оно может вдохновить вас. https://github.com/pvencill/praeter
@muffin добавил информацию о централизации обработки ошибок по запросу.
Спасибо, это хорошо реализовано и тоже объяснено
централизация обработки ошибок и обмена сообщениями для меня звучит как лучшее решение ... не могли бы вы рассказать, как бы вы это сделали?