英文:
Is it expected that the client socket.remotePort changes between routes?
问题
在你提供的代码中,你想要使用客户端的IP地址和端口号以及电子邮件地址来创建一个唯一的哈希值。在signup.js
路由中,req.socket.remotePort
在get
和post
函数中保持不变。但是当路由更改为activation
时,req.socket.remotePort
会递增(始终为前一个端口号加1)。
这是否符合预期?是否有一种方法可以保持稳定和一致的远程端口?
在你的问题中,你需要查看这种行为是否符合预期,并且如果需要保持稳定和一致的远程端口,你可以考虑在signup.js
和authorization
路由之间共享端口号或在会话中存储它,以确保在不同路由之间的一致性。但是请注意,根据网络配置和服务器设置,远程端口可能会有变化。
英文:
I am a creating a Node JS app where I want to use the client's ip and port number along with an email address to create a unique hash. Within the signup route handler, the req.socket.remotePort remains the same in both get and post functions. But when the route is changed to activation, the req.socket.remotePort gets incremented (always previous port number + 1).
Is this expected? Is there way to keep a stable and consistent remote port?
signup.js route
var express = require('express');
var lib = require('../lib.js');
var router = express.Router();
var nodemailer = require('nodemailer');
router.get('/', function(req, res, next) {
if(!Object.hasOwn(req.params, 'email')) {
req.params.email = "";
}
res.render('signup', { title: 'Signup', email: req.params.email, ip: req.socket.remoteAddress, port: req.socket.remotePort });
});
router.post('/', function(req, res, next) {
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'authorize@example.com',
pass: 'abc123'
}});
var hashCode = lib.hashCode(req.body.email + req.socket.remoteAddress + req.socket.remotePort);
var mailOptions = {
from: 'authorize@example.com',
to: req.body.email,
subject: 'Activiation Code',
text: 'Your activiation code is: ' + hashCode
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
res.redirect('/authorize?email=' + req.body.email);
}
});
});
module.exports = router;
Authorization route
var express = require('express');
var lib = require('../lib.js');
var router = express.Router();
router.get('/', function(req, res, next) {
if(!Object.hasOwn(req.query, 'authCode')) {
req.query.authCode = "";
}
res.render('authorize', { title: 'Authorize', email: req.query.email, ip: req.socket.remoteAddress(), port: req.socket.remotePort, authCode: req.query.authCode });
});
router.post('/', function(req, res, next) {
// HERE IS WHERE THE PROBLEM MANIFEST
// the remotePort is different now (last port number + 1)
// so the always generates a different hash and so fails to authorize
var hashCode = lib.hashCode(req.query.email + req.socket.remoteAddress + req.socket.remotePort);
if(hashCode != req.body.authCode) {
console.log('Invalid')
} else {
console.log('Valid')
}
});
module.exports = router;
答案1
得分: 0
短答案是否定的,HTTP 1.1规范不对远程端口做任何保证。这是浏览器利用的事实,以加速它们的请求;客户端到服务器的特定IP和端口组合只能有一个并发连接,所以为了加速浏览器请求,会使用多个连接。根据RFC:「因此,服务器不得假设同一连接上的两个请求来自相同的用户代理,除非连接是安全的并且特定于该代理。已知一些非标准HTTP扩展(例如[RFC4559])曾经违反了这一要求,导致安全性和互操作性问题。」当然,如果您控制客户端和服务器,可以违反规范,但我建议您首先考虑不同的解决方案。
英文:
The short answer is no, the HTTP 1.1 specification does not make any guarantees about the remote port.
This is a fact that has been taken advantage of by browsers to speed up their requests; there can only be one concurrent connection from a client to server on a specific combination of IP and port, so to speed up browser requests multiple connections are used: en.wikipedia.org/wiki/HTTP_persistent_connection
As per the RFC: "As a result, a server MUST NOT assume that two requests on the same connection are from the same user agent unless the connection is secured and specific to that agent. Some non-standard HTTP extensions (e.g., [RFC4559]) have been known to violate this requirement, resulting in security and interoperability problems." https://www.ietf.org/rfc/rfc7230.html
Of course you may violate the specification if you control both the client and server, but I'd urge you to consider a different solution first.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论