[英]How do I get a client's IP address from inside a soap service?(nodejs)
我使用soap 包編寫了一個 soapService,我將一個快速服務器傳遞給它。
問題是服務器可以從 2 個不同的網絡接口獲取請求,而我想知道請求來自哪個接口。
我的解決方案是獲取客戶端的 IP 並確定它來自使用哪個接口
require("os").NetworkInterfaces()
但我找不到如何獲取客戶的 IP
我試過了:this.req.ip, this.httpHeaders["x-forwarded-for"] || this.req.connection.remoteAddres 但它是未定義的
編輯:我想添加一個最小的測試示例。
創建了 3 個文件:soapserver.js(包括我想從其中獲取 ip 的 soap 服務)client.js(調用 soapservice)check_username.wsdl(用於創建服務)
soapserver.js:
var soap = require('soap');
var http = require('http');
const util = require('util');
const app = require("express")()
var myService = {
CheckUserName_Service: {
CheckUserName_Port: {
checkUserName: function(args, soapCallback) {
console.log('checkUserName: Entering function..');
console.log(args);
/*
* Where I'm trying to get clietn's IP address
*/
soapCallback("{'username found'}");
}
}
}
};
var xml = require('fs').readFileSync('check_username.wsdl', 'utf8');
var server = require("http").Server(app);
app.get('/', (req, res) => {
res.send("Hello World!");
console.log(req);
console.log(req.connection.remoteAddress);
console.log(req.ip);
});
var port = 8000;
server.listen(port);
var soapServer = soap.listen(server, '/test', myService, xml);
soapServer.log = function(type, data) {
console.log('Type: ' + type + ' data: ' + data);
};
console.log('SOAP service listening on port ' + port);
客戶端.js:
"use strict";
var soap = require('strong-soap').soap;
var url = 'http://localhost:8000/test?wsdl';
var options = { endpoint: 'http://localhost:8000/test'};
var requestArgs = { userName: "TEST_USER" };
soap.createClient(url, options, function(err, client) {
if (err) {
console.error("An error has occurred creating SOAP client: " , err);
} else {
var description = client.describe();
console.log("Client description:" , description);
var method = client.checkUserName;
method(requestArgs, function(err, result, envelope, soapHeader) {
//response envelope
console.log('Response Envelope: \n' + envelope);
//'result' is the response body
console.log('Result: \n' + JSON.stringify(result));
});
}
});
檢查用戶名.wsdl
<definitions name = "CheckUserNameService"
targetNamespace = "http://www.examples.com/wsdl/CheckUserNameService.wsdl"
xmlns = "http://schemas.xmlsoap.org/wsdl/"
xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns = "http://www.examples.com/wsdl/CheckUserNameService.wsdl"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
<message name = "CheckUserNameRequest">
<part name = "userName" type = "xsd:string"/>
</message>
<message name = "CheckUserNameResponse">
<part name = "status" type = "xsd:string"/>
</message>
<portType name = "CheckUserName_PortType">
<operation name = "checkUserName">
<input message = "tns:CheckUserNameRequest"/>
<output message = "tns:CheckUserNameResponse"/>
</operation>
</portType>
<binding name = "CheckUserName_Binding" type = "tns:CheckUserName_PortType">
<soap:binding style = "rpc"
transport = "http://schemas.xmlsoap.org/soap/http"/>
<operation name = "checkUserName">
<soap:operation soapAction = "checkUserName"/>
<input>
<soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:CheckUserNameService" use = "encoded"/>
</input>
<output>
<soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:CheckUserNameService" use = "encoded"/>
</output>
</operation>
</binding>
<service name = "CheckUserName_Service">
<documentation>WSDL File for CheckUserNameService</documentation>
<port binding = "tns:CheckUserName_Binding" name = "CheckUserName_Port">
<soap:address
location = "http://www.examples.com/CheckUserName/" />
</port>
</service>
</definitions>
給你,代碼。 在 Localhost 和 remoteProd(雲托管)上工作。
編輯:代碼現在也針對遠程客戶端 IP 進行了測試和修改。
服務器.js
var soap = require('soap');
var http = require('http');
const util = require('util');
const fetch = require('node-fetch');
const app = require("express")()
var myService;
newApp = app;
var server = http.Server(app);
var port = 8000;
server.listen(port);
console.log("http server started listtening on " + port);
newApp.get('/', (req, res) => {
res.send("Hello World!");
var clientIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
//console.log(req.connection.remoteAddress); // will always give server ip on remote connections
myService = {
CheckUserName_Service: {
CheckUserName_Port: {
checkUserName: function (args, soapCallback) {
console.log('checkUserName: Entering function..');
console.log(args);
//console.log(this.request.connection.remoteAddress)
/*
* Where I'm trying to get clietn's IP address
*/
console.log("***")
console.log("IP of client: " + clientIP);
console.log("***")
//console.log(request.connection.remoteAddress);
// res = this.request.connection.remoteAddress;
//console.log(args)
soapCallback("{'username found'}");
}
}
}
};
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8');
var soapServer = soap.listen(server, '/test', myService, xml);
soapServer.log = function (type, data) {
console.log('Type: ' + type + ' data: ' + data);
};
console.log('SOAP service listening on port ' + port);
});
// Need first request to boot up soapservice
fetch('http://localhost:8000/', {
method: 'GET'
})
.then((response) => {
console.log("fetch then + first from server");
})
.catch((error) => {
console.log("fetch error + first from server: " + error);
})
客戶端.js
"use strict";
var soap = require('strong-soap').soap;
var fetch = require('node-fetch');
var url = 'http://localhost:8000/test?wsdl';
var options = {
endpoint: 'http://localhost:8000/test'
};
var requestArgs = {
userName: "TEST_USER"
};
// If you comment out this request, server will log server's IP (first fetch)
fetch('http://localhost:8000/', {
method: 'GET'
})
.then((response) => {
console.log("fetch then from client");
})
.catch((error) => {
console.log("fetch error from client: " + error);
})
soap.createClient(url, options, function (err, client) {
if (err) {
console.error("An error has occurred creating SOAP client: ", err);
} else {
var description = client.describe();
console.log("Client description:", description);
var method = client.checkUserName;
method(requestArgs, function (err, result, envelope, soapHeader) {
console.log('Result: \n' + JSON.stringify(result));
});
}
});
myservice.wsdl :請注意我重命名了它,我知道為什么。
<definitions name = "CheckUserNameService"
targetNamespace = "http://www.examples.com/wsdl/CheckUserNameService.wsdl"
xmlns = "http://schemas.xmlsoap.org/wsdl/"
xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns = "http://www.examples.com/wsdl/CheckUserNameService.wsdl"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
<message name = "CheckUserNameRequest">
<part name = "userName" type = "xsd:string"/>
</message>
<message name = "CheckUserNameResponse">
<part name = "status" type = "xsd:string"/>
</message>
<portType name = "CheckUserName_PortType">
<operation name = "checkUserName">
<input message = "tns:CheckUserNameRequest"/>
<output message = "tns:CheckUserNameResponse"/>
</operation>
</portType>
<binding name = "CheckUserName_Binding" type = "tns:CheckUserName_PortType">
<soap:binding style = "rpc"
transport = "http://schemas.xmlsoap.org/soap/http"/>
<operation name = "checkUserName">
<soap:operation soapAction = "checkUserName"/>
<input>
<soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:CheckUserNameService" use = "encoded"/>
</input>
<output>
<soap:body encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" namespace = "urn:examples:CheckUserNameService" use = "encoded"/>
</output>
</operation>
</binding>
<service name = "CheckUserName_Service">
<documentation>WSDL File for CheckUserNameService</documentation>
<port binding = "tns:CheckUserName_Binding" name = "CheckUserName_Port">
<soap:address
location = "http://www.examples.com/CheckUserName/" />
</port>
</service>
</definitions>
我找到了適合我的情況的解決方案,並且可能對想要做類似事情的人有用。
我有 2 個潛在的解決方案:
1 / 我修改了'node-soap'包,在server.js
中我將IP(從req對象)傳遞給_process
而不是將它包含在將要傳遞的參數中obj.Body[methodName]["ip"] = ip;
2/ 目標是找到來自哪個網絡接口,因此第二種解決方案涉及將服務器僅綁定到一個接口(而不是 0.0.0.0),並通過接口擁有一個服務器。
在我的情況下,我選擇了前者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.