এক্সপ্রেস.জেএস: দূরবর্তী ক্লায়েন্টের ঠিকানা কীভাবে পাবেন


256

আমি কীভাবে দূরবর্তী ব্যবহারকারীর আইপি অ্যাড্রেস পেতে পারি তা আমি পুরোপুরি বুঝতে পারি না।

ধরা যাক আমার কাছে একটি সাধারণ অনুরোধের রুট রয়েছে যেমন:

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];  
   }
});

প্রকৃত ব্যবহারকারীর আইপি অ্যাড্রেস পাওয়ার জন্য কি উপরোক্ত পদ্ধতির অবস্থানটি সঠিক বা আরও ভাল উপায় আছে? এবং প্রক্সি সম্পর্কে কি?


1
এখানে ব্যাখ্যা অনুযায়ী নোড-আইপওয়্যার ব্যবহার সম্পর্কে কীভাবে ।
un33k

: আপনি পছন্দ 'example.com' req.hostname পেতে পারে না যদি stackoverflow.com/a/37824880/5333284
zhi.yang

উত্তর:


468

আপনি যদি এনজিআইএনএক্স-এর মতো কোনও প্রক্সিটির পিছনে ছুটে চলেছেন বা আপনার কাছে কী রয়েছে তবে কেবলমাত্র আপনার 'এক্স-ফরওয়ার্ড-ফর' পরীক্ষা করা উচিত:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

প্রক্সিটি যদি 'আপনার' না হয় তবে আমি 'এক্স-ফরোয়ার্ড-ফর' শিরোনামকে বিশ্বাস করব না, কারণ এটি ছদ্মবেশী হতে পারে।


2
এটি সঠিক, তবে আমার পরিস্থিতিতে আমাকে বর্গাকার বন্ধনী ব্যবহার করতে হয়েছিল (উপরের সম্পাদনা দেখুন) এছাড়াও আপনার এনজিএনএক্স কনফিগারেশনে এক্স-ফরোয়ার্ড-সক্রিয় আছে তা নিশ্চিত করুন। একটি যাদুমন্ত্র মত কাজ করে!
নব্বই শত শত

43
আপনার নিজের মনে রাখতে হবে যে আপনি proxy_set_header X-Forwarded-For $remote_addr;যদি নিজের বিপরীত প্রক্সি ব্যবহার করছেন তবে আপনাকে এই নির্দেশটি আপনার এনজিএনএক্স কনফিগারেশনের মধ্যে রাখতে হবে ।
কক্সার 12

আপনি যদি ব্রাউজারে আইপি ব্যবহার করার পরিকল্পনা করেন তবে http (গুলি): // [ipv6]: বন্দরটি লক্ষ্য করুন [] প্রয়োজন, আশা করি এটি সহায়তা করে
psuhas

43
কপি-পাস্তা ব্যবহারকারীরা দয়া করে নোট করুন: এটি আইপি ঠিকানার কমা দ্বারা পৃথক করা তালিকা ফিরিয়ে দিতে পারে। আমাদের কোনও ডিভ থেকে একটি বাগ এসেছিল এটি অনুলিপি করে এবং ফলাফলটির সাথে আইপি তুলনা করে। var ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress || '').split(',')[0].trim();ক্লায়েন্টের আইপি পেতে সম্ভবত কিছু করুন ।
ডেভি জোনস

3
@ রিশভ :: 1 হ'ল লোকহোস্টের আইপিভি 6 ঠিকানা
ড্যানিয়েল ও

238

@Alessioalex এর উত্তর কাজ করার সময়, এক্সপ্রেসের প্রক্সি বিভাগের পিছনে এক্সপ্রেসে বর্ণিত অন্য একটি উপায় রয়েছে - গাইড

  1. যোগ app.set('trust proxy', true)আপনার দ্রুতগামী আরম্ভের কোডে।
  2. আপনি যখন রিমোট ক্লায়েন্টের আইপি পেতে চান, ব্যবহার করুন req.ipবা req.ipsস্বাভাবিক উপায়ে (যেন কোনও বিপরীত প্রক্সি নেই)

Readingচ্ছিক পড়া:

  • ব্যবহার করুন req.ipবা req.ipsreq.connection.remoteAddressএই সমাধান সঙ্গে কাজ করে না।
  • জন্য আরো বিকল্প 'trust proxy'যদি আপনি সবকিছু নির্ভর চেয়ে আরো পরিশীলিত কিছু মাধ্যমে গৃহীত প্রয়োজন উপলভ্য x-forwarded-for(যেমন, যখন আপনার প্রক্সি preexisting এক্স-ফরওয়ার্ড-জন্য হেডার অবিশ্বস্ত সূত্র থেকে মুছে যায় না) শিরোনাম। আরও তথ্যের জন্য লিঙ্কযুক্ত গাইড দেখুন।
  • যদি আপনার প্রক্সি সার্ভারটি শিরোলেখকে x-forwarded-forজনিত না করে তবে দুটি সম্ভাবনা রয়েছে।
    1. প্রক্সি সার্ভারটি যেখানে অনুরোধটি মূলত ছিল সেখানে তথ্য রিলে করে না। এই ক্ষেত্রে, অনুরোধটি মূলত কোথা থেকে এসেছে তা জানার কোনও উপায় থাকবে না। আপনাকে প্রথমে প্রক্সি সার্ভারের কনফিগারেশনটি পরিবর্তন করতে হবে।
      • উদাহরণস্বরূপ, আপনি যদি নিজের বিপরীত প্রক্সি হিসাবে এনগিনেক্স ব্যবহার করেন তবে proxy_set_header X-Forwarded-For $remote_addr;আপনার কনফিগারেশনে আপনাকে যুক্ত করতে হতে পারে ।
    2. প্রক্সি সার্ভারটি অনুরোধটি মূলত মালিকানাধীন ফ্যাশনের (উদাহরণস্বরূপ, কাস্টম এইচটিপি শিরোনাম) থেকে প্রাপ্ত তথ্য সম্পর্কিত করে ys এই ক্ষেত্রে, এই উত্তর কার্যকর হবে না। সেই তথ্যটি বের করার একটি কাস্টম উপায় থাকতে পারে, তবে আপনাকে প্রথমে প্রক্রিয়াটি বোঝা দরকার।

4
আমার উত্তরটি আরও সাধারণ ছিল (এক্সপ্রেসের সাথে আবদ্ধ নয়) তবে আপনি যদি এক্সপ্রেস ব্যবহার করেন তবে এটাই সর্বোত্তম উপায়।
এলেসিয়োএলেক্স

4
আপনার প্রক্সি সার্ভারে শিরোনামটি 'এক্স-ফরওয়ার্ড-ফর' দূরবর্তী ঠিকানায় সেট করতে হবে। উদাহরণস্বরূপ, এনগিনেক্সের ক্ষেত্রে আপনার কনফিগার ফাইলে আপনার প্রক্সি_সেট_হেডার এক্স-ফরওয়ার্ড-ফর $ রিমোট_এড্রির হওয়া উচিত
কামাটাগোস

1
আইআইএসনোডের সাথে আইআইএসের পিছনে প্রক্সি হিসাবে app.enable('trust proxy')ব্যবহার করা খুব বেশি কাজ করে req.ip। আমি ছাড়া এটি বন্দর পেতে 1.2.3.4:56789। এটি সরিয়ে var ip = req.ip.split(':')[0]
ফেলার জন্য

এই সমাধান কি নিরাপদ?
ড্যানিয়েল কুমাক

3
আমি অনুভব করি যে এই উত্তরে সুরক্ষার অভাব রয়েছে এবং আপডেট করার প্রয়োজন রয়েছে। আপনার সর্বদা নির্ধারণ করা উচিত যা আপনার অ্যাপ্লিকেশনটির উপর নির্ভর করে। স্বীকৃত উত্তরের কমপক্ষে স্পোফিং সম্পর্কে একটু বিজ্ঞপ্তি রয়েছে। এটি বলেছিল, আপনি যদি এক্সপ্রেস ব্যবহার করেন তবে এটির মতো লাইব্রেরিটি ব্যবহার করা ভাল সমাধান, তবে উদ্ধৃত কোডটি ভুল এবং সংযুক্ত সংস্থানটিতে পাওয়া যায় নি found
ফিল

54

ইন nginx.confফাইল:
proxy_set_header X-Real-IP $remote_addr;

ইন node.jsসার্ভার ফাইল:
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

লক্ষ্য করুন যে লোয়ারকেস শিরোনামকে প্রকাশ করে


3
স্ট্যাক ওভারফ্লোতে স্বাগতম! কেবল কোডের একটি ব্লক পোস্ট করার পরিবর্তে দয়া করে ব্যাখ্যা করুন যে এই কোডটি কেন ডেকে আনা সমস্যা সমাধান করে। কোনও ব্যাখ্যা ছাড়াই এটি কোনও উত্তর নয়।
আর্টেমিক্স

1
@ কোকজোন এর উত্তর ঠিক আছে। ব্যাখ্যাটি "এক্স-রিয়েল-আইপি" নামের অনুরোধে একটি কাস্টম শিরোনাম সেট করা হয়েছে যা দর্শনার্থীর কাছ থেকে মূল আইপি ঠিকানা নেয়। এটি নোড এবং সকেট.ওয়ের সাথে আমার জন্য কাজ করে।
coffekid

8
আমার জন্য, আইপি ঠিকানা req.headers['x-real-ip']এমনকি nginx.confশিরোনামের অধীনে উপলব্ধ বড় হাতের অক্ষরের সাথে সেট করা আছে।
নিক সুমিকো

এটিই আমার জন্য সমাধান করেছে। এমনকি বিশ্বাস-প্রক্সিটি সেট করা সত্য হলেও এটি এখনও স্থানীয় 127.0.0.1 ঠিকানা ব্যবহার করে যাচ্ছিল
ডেভিড

30

বিশেষত নোডের জন্য, ইভেন্ট সংযোগের অধীনে http সার্ভার উপাদানটির ডকুমেন্টেশন বলে:

[ট্রিগারড] যখন নতুন টিসিপি স্ট্রিম প্রতিষ্ঠিত হয়। [সকেট] টাইপ নেট.সকেটের একটি অবজেক্ট। সাধারণত ব্যবহারকারীরা এই ইভেন্টটি অ্যাক্সেস করতে চান না। প্রোটোকল পার্সার কীভাবে সকেটে সংযুক্ত করে সে কারণে বিশেষত, সকেটটি পঠনযোগ্য ইভেন্টগুলি ছড়াবে না। সকেটেও অ্যাক্সেস করা যায় request.connection

সুতরাং, তার মানে request.connectionএকটি সকেট এবং ডকুমেন্টেশন অনুযায়ী সেখানে প্রকৃতপক্ষে একটি হল socket.remoteAddress অ্যাট্রিবিউট যা অনুযায়ী ডকুমেন্টেশন হল:

দূরবর্তী আইপি ঠিকানার স্ট্রিং প্রতিনিধিত্ব। উদাহরণস্বরূপ, '74 .125.127.100 'বা' 2001: 4860: a005 :: 68 '।

এক্সপ্রেসের অধীনে, অনুরোধ অবজেক্টটি নোড http অনুরোধের বস্তুরও একটি উদাহরণ, তাই এই পদ্ধতির এখনও কাজ করা উচিত।

তবে, এক্সপ্রেস.জেএস এর অধীনে অনুরোধটির ইতিমধ্যে দুটি বৈশিষ্ট্য রয়েছে: রেকিআইপি এবং রেকিআইপিএস

req.ip

দূরবর্তী ঠিকানাটি ফেরত দিন, বা যখন "বিশ্বাসের প্রক্সি" সক্ষম করা হবে - প্রবাহের ঠিকানা।

req.ips

যখন "বিশ্বাস প্রক্সি" হয় true, "এক্স-ফরওয়ার্ড-ফর" আইপি ঠিকানার তালিকা পার্স করে একটি অ্যারে ফিরিয়ে দিন, অন্যথায় একটি ফাঁকা অ্যারে ফিরে আসে। উদাহরণস্বরূপ মানটি যদি "ক্লায়েন্ট, প্রক্সি 1, প্রক্সি 2" হয় তবে আপনি অ্যারে ["ক্লায়েন্ট", "প্রক্সি 1", "প্রক্সি 2"] পাবেন যেখানে "প্রক্সি 2" সবচেয়ে দূরে ডাউন স্ট্রিম।

এটা তোলে কহতব্য যে, আমার বোঝার অনুযায়ী, এক্সপ্রেস হতে পারে req.ipচেয়ে ভাল পন্থা req.connection.remoteAddressসাল থেকে req.ip(প্রদত্ত যেটা বিশ্বস্ত প্রক্সি এক্সপ্রেসে সক্ষম হয়) প্রকৃত ক্লায়েন্ট IP রয়েছে, যেহেতু অন্যান্য প্রক্সি IP ঠিকানার থাকতে পারে (যদি থাকে এক).

এই কারণেই বর্তমানে গৃহীত উত্তরগুলি পরামর্শ দেয়:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

req.headers['x-forwarded-for']দ্রুতগামী সমতুল্য হতে হবে req.ip


11
  1. যোগ app.set('trust proxy', true)
  2. সাধারণভাবে req.ipবা ব্যবহার করুনreq.ips

2
এই পথেই যেতে হবে। বিস্তারিত জানার জন্য এক্সপ্রেজস /en/guide/behind-proxies.html দেখুন ।
ও জোনস

এত সহজ এবং সংক্ষিপ্ত। একটি সহজ উত্তর পছন্দ।
গিলবার্ট-ভি

7

এটি এই উত্তরের জন্য অতিরিক্ত তথ্য ।

আপনি যদি ব্যবহার করে থাকেন nginxতবে proxy_set_header X-Real-IP $remote_addr;আপনি সাইটের জন্য লোকেশন ব্লকে যুক্ত হবেন। /etc/nginx/sites-available/www.example.comউদাহরণ স্বরূপ. এখানে সার্ভার ব্লকের একটি উদাহরণ রয়েছে।

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.1.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

পুনঃসূচনা করার পরে nginx, আপনি আপনার node/ expressঅ্যাপ্লিকেশন রুটের সাথে আইপি অ্যাক্সেস করতে সক্ষম হবেনreq.headers['x-real-ip'] || req.connection.remoteAddress;


3

প্রক্সিগুলির পিছনে এক্সপ্রেস অনুসারে , req.ipআপনি trust proxyসঠিকভাবে কনফিগার করেছেন তবে বিপরীত প্রক্সি অ্যাকাউন্টে নিয়েছে । অতএব এটি req.connection.remoteAddressনেটওয়ার্ক স্তর থেকে প্রাপ্ত এবং প্রক্সি সম্পর্কে অবগত না থেকে এটি আরও ভাল ।


3

আমি সেই উদ্দেশ্যে একটি প্যাকেজ লিখেছিলাম। আপনি এটি এক্সপ্রেস মিডলওয়্যার হিসাবে ব্যবহার করতে পারেন। আমার প্যাকেজটি এখানে প্রকাশিত হয়েছে: https://www.npmjs.com/package/express-ip

আপনি মডিউলটি ব্যবহার করে ইনস্টল করতে পারেন

npm i express-ip

ব্যবহার

const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);

app.get('/', function (req, res) {
    console.log(req.ipInfo);
});

1
আপনার অধিভুক্ত কোনও কিছুর সাথে লিঙ্ক করার সময় আপনাকে অবশ্যই পোস্টে অনুমোদিততা প্রকাশ করতে হবে । আপনি যদি অনুমোদিততা প্রকাশ না করেন তবে এটি স্প্যাম হিসাবে বিবেচিত হবে। প্রকাশ অবশ্যই স্পষ্ট হওয়া উচিত, তবে আনুষ্ঠানিক হওয়ার দরকার নেই (যেমন আপনার নিজস্ব ব্যক্তিগত সামগ্রীর জন্য: "আমার সাইটে…", "আমার ব্লগে…", ইত্যাদি)। দেখুন: "ভাল" স্ব প্রচারের কী বোঝায়? , স্ব-প্রচার সম্পর্কে কিছু টিপস এবং পরামর্শ , স্ট্যাক ওভারফ্লোর জন্য "স্প্যাম" এর সঠিক সংজ্ঞা কী? , এবং কি কিছু স্প্যাম করে তোলে
মাকেন

2

আমি জানি এই প্রশ্নের উত্তর দেওয়া হয়েছে, তবে আমি কীভাবে আমার কাজে লাগলাম তা এখানে।

let ip = req.connection.remoteAddress.split(`:`).pop();

2

যদি আপনি তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করে ভাল থাকেন। আপনি অনুরোধ-আইপি চেক করতে পারেন

আপনি এটি ব্যবহার করতে পারেন

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

উত্স কোডটি বেশ দীর্ঘ, সুতরাং আমি এখানে অনুলিপি করব না, আপনি এটি পরীক্ষা করতে পারেন https://github.com/pbojinov/request-ip/blob/master/src/index.js

মূলত,

এটি অনুরোধে নির্দিষ্ট শিরোনামের সন্ধান করে এবং যদি অস্তিত্ব না থাকে তবে কিছু ডিফল্টে ফিরে যায় back

ব্যবহারকারী আইপি নিম্নলিখিত আদেশ দ্বারা নির্ধারিত হয়:

  1. X-Client-IP
  2. X-Forwarded-For (শিরোনাম একাধিক আইপি ঠিকানা ফর্ম্যাটে ফিরে আসতে পারে: "ক্লায়েন্ট আইপি, প্রক্সি 1 আইপি, প্রক্সি 2 আইপি", তাই আমরা প্রথমটি গ্রহণ করি))
  3. CF-Connecting-IP (ক্লাউডফ্লেয়ার)
  4. Fastly-Client-Ip (মেঘের ক্রিয়াকলাপের প্রতিশ্রুতি জানালে দ্রুত সিডিএন এবং ফায়ারবেস হোস্টিং শিরোনাম)
  5. True-Client-Ip (আকামাই এবং ক্লাউডফ্লেয়ার)
  6. X-Real-IP (এনগিনেক্স প্রক্সি / ফাস্টসিজিআই)
  7. X-Cluster-Client-IP (র‌্যাকস্পেস এলবি, রিভারবেড স্টিংরে)
  8. X-Forwarded, Forwarded-Forএবং Forwarded(# 2 এর পার্থক্য)
  9. req.connection.remoteAddress
  10. req.socket.remoteAddress
  11. req.connection.socket.remoteAddress
  12. req.info.remoteAddress

যদি কোনও আইপি ঠিকানা না পাওয়া যায় তবে তা ফিরে আসবে null

প্রকাশ: আমি গ্রন্থাগারের সাথে যুক্ত নই।


1

এটি আমার জন্য বাকীগুলির চেয়ে ভাল কাজ করেছে। আমার সাইটগুলি ক্লাউডফ্লেয়ারের পিছনে এবং এটি মনে হচ্ছে এটির প্রয়োজন cf-connecting-ip

req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress

প্রক্সিগুলির পিছনে এক্সপ্রেস পরীক্ষা করেনি কারণ এটি এই cf-connecting-ipশিরোলেখ সম্পর্কে কিছুই বলেনি ।


1

পারে-শিখা, এনগিনেক্স এবং এক্স-রিয়েল-আইপি সমর্থন সহ

var user_ip;

    if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
      let first = req.headers['cf-connecting-ip'].split(', ');
      user_ip = first[0];
    } else {
      let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }

1

আমার ক্ষেত্রে, এই সমাধানের অনুরূপ , আমি নিম্নলিখিত এক্স-ফরওয়ার্ড-ফর অ্যাপ্রোচটি ব্যবহার করে শেষ করেছি :

let ip = (req.headers['x-forwarded-for'] || '').split(',')[0];

x-forwarded-forশিরোনামটি চূড়ান্ত গন্তব্য সার্ভারে উত্স থেকে আইপিটির রুট যুক্ত করা চালিয়ে যাবে, সুতরাং আপনি যদি মূল ক্লায়েন্টের আইপি পুনরুদ্ধার করতে চান তবে এটি অ্যারের প্রথম আইটেম হবে ।


0

var ip = req.connection.remoteAddress;

আইপি = আইপি.স্প্লিট (':') [3];


আউটপুটটি এর মতো: - :: এফএফএফএফএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএর থেকে আমরা আইপি করব
ভুলওয়াত অজয়

3
আমি মনে করি ip = ip.split(':').pop();যদি এই ক্ষেত্রে স্বাভাবিক আইপি অর্থাৎ 127.0.0.1 আসে তবে এটি আপনাকে আইপি দিতে সক্ষম হবে।
9me

0

শিরোনামের অবজেক্টে আপনার প্রয়োজনীয় সমস্ত কিছুই রয়েছে, কেবল এটি করুন:

var ip = req.headers['x-forwarded-for'].split(',')[0];

0

সমস্ত একসাথে বুদ্ধিযুক্ত @kakopappa সমাধান প্লাস্টিক morganআইপি ঠিকানায় লগিং করা:

morgan.token('client_ip', function getId(req) {
    return req.client_ip
});
const LOG_OUT = ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :client_ip'
self.app.use(morgan(LOG_OUT, {
    skip: function(req, res) { // custom logging: filter status codes
        return res.statusCode < self._options.logging.statusCode;
    }
}));

// could-flare, nginx and x-real-ip support
var getIpInfoMiddleware = function(req, res, next) {
    var client_ip;
    if (req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
        var first = req.headers['cf-connecting-ip'].split(', ');
        client_ip = first[0];
    } else {
        client_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }
    req.client_ip = client_ip;
    next();
};
self.app.use(getIpInfoMiddleware);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.