#javascript #node.js #spring-mvc #express #proxy
#javascript #node.js #spring-mvc #выразить #прокси
Вопрос:
Я относительный новичок в Node.js . Прошло два дня, когда я пытаюсь изменить тело запроса в Node.js а затем переадресовал его. Для проксирования я использую http-proxy
module.
Что мне нужно сделать, так это перехватить пароль пользователя внутри объекта JSON, зашифровать его и установить новый зашифрованный пароль внутри тела запроса.
Проблема в том, что каждый раз, когда я пытаюсь собрать тело запроса, я его использую (т. Е. Использую body-parser
). Как я могу выполнить эту задачу? Я знаю, что запрос в узле рассматривается как поток.
Для полноты картины я использую express
для цепочки несколько операций перед проксированием.
Редактировать
Тот факт, что я должен проксировать запрос, не бесполезен. Он следует коду, который я пытаюсь использовать.
function encipher(req, res, next){
var password = req.body.password;
var encryptionData = Crypto().saltHashPassword(password);
req.body.password = encryptionData.passwordHash;
req.body['salt'] = encryptionData.salt;
next();
}
server.post("/users", bodyParser.json(), encipher, function(req, res) {
apiProxy.web(req, res, {target: apiUserForwardingUrl});
});
Сервер (REST, созданный Spring MVC) выдает мне исключение Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: null
Ответ №1:
Реальная проблема заключается в том, что существует проблема интеграции между модулями body-parser
и http-proxy
, как указано в этой теме .
Одним из решений является настройка body-parser
after http-proxy
. Если вы не можете изменить порядок промежуточного программного обеспечения (как в моем случае), вы можете повторно передать проанализированное тело перед проксированием запроса.
// restream parsed body before proxying
proxy.on('proxyReq', function(proxyReq, req, res, options) {
if (req.body) {
let bodyData = JSON.stringify(req.body);
// if content-type is application/x-www-form-urlencoded -> we need to change to application/json
proxyReq.setHeader('Content-Type','application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
// stream the content
proxyReq.write(bodyData);
}
}
Комментарии:
1. Это выдает ошибку
Can't set headers after they are sent.
. Cf. github.com/nodejitsu/node-http-proxy/issues/1168 и github.com/nodejitsu/node-http-proxy/issues/908 .2. На всякий случай, если это полезно для других: для меня я добавлял больше информации в полезную нагрузку, поэтому обновление длины содержимого было очень важно. Мне также пришлось включить
proxyReq.end()
afterproxyReq.write()
или запрос, казалось, закрылся без каких-либо указаний на причину.3. Будьте осторожны с
if (req.body)
, поскольку{}
это «правдиво». Лучше проверять реквизиты в объекте body:if (!!req.body amp;amp; Object.keys(req.body).length > 0)
Ответ №2:
Почему бы не использовать для этого экспресс-цепочку? В вашей первой функции просто сделайте что-то вроде этого :
req.body.password = encrypt(req.body.password); next();
Комментарии:
1. Должен ли я сначала связать body-parser? Потому что я заметил, что он использует запрос.
2. Вы должны использовать body-parser в своей экспресс-конфигурации, например :
app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json());
3. И он не использует запрос? Будет ли оно доступно для следующего промежуточного программного обеспечения?
4. bodyParser преобразует каждый запрос вашего сервера, затем в каждом промежуточном программном обеспечении вы сможете делать то, что хотите, с
req.body
Ответ №3:
Вам просто нужно использовать промежуточное программное обеспечение.
body-parser
это также просто промежуточное программное обеспечение, которое анализирует тела запросов и помещает его под req.body
Вы можете сделать что-то вроде этого:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
function encryptPassword(req, res, next) {
req.body.password = encrypt(req.body.password);
// You can do anything really here and modify the req
//call next after you are done to pass on to next function
next();
}
app.use(encryptPassword);
Обычно люди используют промежуточные программы для аутентификации, управления доступом на основе ролей и т. Д…..
Вы также можете использовать промежуточные программы в определенных маршрутах:
app.post('/password', encryptPassword, function(req, res) {
// Here the req.body.password is the encrypted password....
// You can do other operations related to this endpoint, like store password in database
return res.status(201).send("Password updated!!");
});
Комментарии:
1. Попробуйте зарегистрировать свой req.body перед вызовом apiProxy и предоставьте нам этот журнал.