簡體   English   中英

如何從 soap 服務中獲取客戶端的 IP 地址?(nodejs)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM