লারাভেল 5+ এ কীভাবে ক্লায়েন্টের আইপি ঠিকানা পাবেন


136

আমি ক্লায়েন্টের আইপি ঠিকানা লারাভেলে পাওয়ার চেষ্টা করছি to

পিএইচপি ব্যবহার করে ক্লায়েন্টের আইপি পাওয়া সহজ $_SERVER["REMOTE_ADDR"] । এটি মূল পিএইচপি-তে দুর্দান্ত কাজ করছে, তবে আমি যখন লারাভেলে একই জিনিসটি ব্যবহার করি তখন এটি দর্শকের আইপির পরিবর্তে সার্ভার আইপি ফেরত দেয়।

উত্তর:


194

লারাভেল এপিআইয়ের দিকে তাকানো :

Request::ip();

অভ্যন্তরীণভাবে, এটি সিমফনি অনুরোধ অবজেক্টgetClientIps থেকে পদ্ধতিটি ব্যবহার করে :

public function getClientIps()
{
    $clientIps = array();
    $ip = $this->server->get('REMOTE_ADDR');
    if (!$this->isFromTrustedProxy()) {
        return array($ip);
    }
    if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
        $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
        preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches);
        $clientIps = $matches[3];
    } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
        $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
    }
    $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
    $ip = $clientIps[0]; // Fallback to this when the client IP falls into the range of trusted proxies
    foreach ($clientIps as $key => $clientIp) {
        // Remove port (unfortunately, it does happen)
        if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
            $clientIps[$key] = $clientIp = $match[1];
        }
        if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
            unset($clientIps[$key]);
        }
    }
    // Now the IP chain contains only untrusted proxies and the client IP
    return $clientIps ? array_reverse($clientIps) : array($ip);
} 

3
অনুরোধ অবজেক্টটি ব্যবহার করা আমার পক্ষে কাজ করে না, এটি আমার হোমস্টেড সার্ভারের ঠিকানা ফেরত দেয়। 192.168.10.10 যা অবশ্যই আমার আইপি ঠিকানা নয় address
ভিন্স ক্রোনলাইন 13'17

আপনার মামলার জন্য @ ভিনস ক্রোনলিন এই উত্তরটি দেখুন stackoverflow.com/a/41769505/3437790
সেবাস্তিয়ান হরিন

3
আপনার ক্ষেত্রে @ ভিনস ক্রোনলিন এটি খুব সঠিক ছিল। আপনি হোমস্টেড অ্যাক্সেস করার কারণে, আপনার স্থানীয় নেটওয়ার্কে, আপনি 192. আইপি পেয়েছিলেন। যদি আপনি অন্য কারও বাসস্থান সার্ভারটি ইন্টারনেটের মাধ্যমে অ্যাক্সেস করেন তবে আপনার আইপিটি আপনার আইএসপি এর মাধ্যমে বেরিয়ে আসত এবং আপনার সর্বজনীন ব্যবহার করা হত।
ied3vil

83

আপনি যদি কোনও ভারসাম্য রক্ষাকারী হিসাবে থাকেন তবে লারাভেলস \Request::ip() সর্বদা ব্যালেন্সারের আইপি প্রদান করে:

            echo $request->ip();
            // server ip

            echo \Request::ip();
            // server ip

            echo \request()->ip();
            // server ip

            echo $this->getIp(); //see the method below
            // clent ip

এই কাস্টম পদ্ধতিটি আসল ক্লায়েন্ট আইপি প্রদান করে:

public function getIp(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip){
                $ip = trim($ip); // just to be safe
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    return $ip;
                }
            }
        }
    }
}

এগুলি ছাড়াও আমি আপনাকে লারাভেলের থ্রটল মিডলওয়্যারটি ব্যবহার করে খুব সতর্কতা অবলম্বন করার পরামর্শ দিচ্ছি : এটি লারাভেলকেও ব্যবহার করে Request::ip(), সুতরাং আপনার সমস্ত দর্শক একই ব্যবহারকারী হিসাবে চিহ্নিত হবে এবং আপনি খুব শীঘ্রই থ্রটল সীমাতে আঘাত হানবেন। আমি এই লাইভটি অভিজ্ঞতা পেয়েছি এবং এর ফলে বড় সমস্যার সৃষ্টি হয়েছে।

এটি ঠিক করতে:

জ্বালান \ http \ Request.php

    public function ip()
    {
        //return $this->getClientIp(); //original method
        return $this->getIp(); // the above method
    }

আপনি এখন এটিও ব্যবহার করতে পারেন Request::ip(), যা উত্পাদনে আসল আইপি ফিরিয়ে আনতে হবে।


1
দ্বিতীয় ফোরচের ভিতরে যদি (ফিল্টার_ভার ...) সঠিক হয়? এই কোডটি কখনই কার্যকর করা হবে না।
মিসট্রে 83

@ মিস্ট্রে 83৮ হ্যাঁ আপনি ঠিক বলেছেন, আমি মনে করি এটি একটি পরীক্ষা পর্যবেক্ষণ। আমি এটি আপডেট!
সেবাস্তিয়ান হরিন

6
এটি আসলে লারাভেল 5.4 এর সাথে কাজ করে দয়া করে গিথুবগুলিতে PR তৈরির বিষয়টি বিবেচনা করুন। আমি মনে করি এটি ডিফল্ট আচরণ হওয়া উচিত
ক্রিস্টাল


3
আপনি বিশ্বস্ত প্রক্সি দিয়ে এটি ঠিক করতে পারেন? - laravel.com/docs/master/requests#configuring-trusted-proxies
user2722667

74

ব্যবহার request()->ip()

আমি যা বুঝতে পারি তা থেকে লারাভেল 5 যেহেতু বিশ্বব্যাপী ফাংশনগুলি ব্যবহার করার পরামর্শ দেওয়া / ভাল অনুশীলন:

response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();

এবং যদি কিছু থাকে তবে স্থির স্বরলিপি পরিবর্তে ফাংশনগুলি ব্যবহার করার সময় আমার আইডিই ক্রিসমাস ট্রিের মতো আলোকিত হয় না।


3
আপনি ঠিক বলেছেন যে requestএকটি "গ্লোবাল" ফাংশন - এটি ল্যারাভেল দ্বারা সরবরাহিত বৈশ্বিক সহায়ক ফাংশনগুলির মধ্যে একটি। তবে অনুরোধের সম্মুখভাগটি স্থির নয় (পদ্ধতিটি আইপিও নয়) - request()->fooএবং Reqest::fooএবং $request->fooসমস্ত অভিন্ন। উদাহরণটির জন্য এই গিস্টটি দেখুন
ক্রিস

1
যথেষ্ট ন্যায্য - উভয়ই সমানভাবে সঠিক। আমি কেবল কিছুটা ভেবেছিলাম যেখানে আপনি বলেছিলেন "এটি Request::ipবিভ্রান্তিকর হতে পারে না
ক্রিস

3
সমস্যাটি হ'ল এই গ্লোবাল ফাংশনগুলি সহজেই টেস্টযোগ্য হয় না — এগুলি উপহাস করা যায় না। ফেইডস হতে পারে। আমি গ্লোবাল ফাংশনগুলি এড়াতে চেষ্টা করি, যেহেতু এর অর্থ হ'ল গ্লোবাল ফাংশন উত্সের মাধ্যমে তার কলগুলি উপহাস করা, যা অতিরিক্ত কাজ, বিরক্তিকর এবং আমার দায়িত্ব হওয়া উচিত নয়।
হ্যাকেল

1
যদিও request()->ip()সঠিক, পার্শ্ববর্তী লেখা সত্যিই বিভ্রান্তিকর হয় - বিশেষ করে বলতে "এটা না Request::ip
ক্রিস

1
@ ক্রিস ধন্যবাদ, আপনি একেবারে ঠিক বলেছেন। স্বচ্ছতার জন্য সম্পাদিত!
স্টান স্মুল্ডার্স

27

নাম স্থান যোগ করুন

use Request;

তারপরে ফাংশনটি কল করুন

Request::ip();

1
আপনার যদি নেমস্পেস ব্যবহার করে থাকে: -> আলোকিত \ এইচটিটিপি \ অনুরোধ ব্যবহার করুন;
দু'জনের

মূল উত্তরটি সঠিক। আপনাকে আমদানি করতে হবে use Requestকারণ আপনি মুখোমুখি ব্যবহার করার চেষ্টা করছেন। আপনার সরবরাহ করা নেমস্পেস অন্তর্নিহিত শ্রেণীর জন্য। যদি আপনি আমদানি করেন যে আপনি একটি ত্রুটি পাবেন কারণ ip()স্ট্যাটিকালি বলা যায় না, এটিই হ'ল ফ্যাকাস।
jfadich

তুমি ক্লাসে আমদানি বিরক্ত করার জন্য চলুন, তাহলে আপনি প্রকৃত ছদ্মরূপ না ওরফে ব্যবহার করা উচিত: use Illuminate\Support\Facades\Request। যদি না হয়, শুধু ব্যবহার করুন \Request::
হ্যাকেল

18

লারাভেল 5 এর জন্য আপনি অনুরোধটি অবজেক্টটি ব্যবহার করতে পারেন। কেবল এর ip()পদ্ধতিটি কল করুন , এরকম কিছু:

$request->ip();


12

দুটি বিষয় খেয়াল রাখতে হবে:

  1. একটি সহায়তা ফাংশন পান যা একটি প্রদান করে Illuminate\Http\Requestএবং ->ip()পদ্ধতিটি কল করে :

    request()->ip();
  2. আপনার সার্ভারের কনফিগারেশনটির কথা চিন্তা করুন, এটি কোনও প্রক্সি বা load-balancerবিশেষত AWS ELB কনফিগারেশনে ব্যবহার করতে পারে ।

এটি যদি আপনার ক্ষেত্রে হয় তবে আপনাকে " বিশ্বস্ত প্রক্সি কনফিগারেশন " অনুসরণ করতে হবে বা একটি "সমস্ত প্রক্সি বিশ্বাস করে" বিকল্পটি সেট করতে হবে।

কেন? কারণ আপনার সার্ভার হওয়ার কারণে এর load-balancerপরিবর্তে আপনার প্রক্সি / আইপি পাবেন।

আপনি যদি এডাব্লুএসের ভারসাম্য-লোডারে থাকেন তবে যান App\Http\Middleware\TrustProxiesএবং $proxiesঘোষণাটিকে এর মতো দেখান:

protected $proxies = '*';

এখন এটি পরীক্ষা করুন এবং উদযাপন করুন কারণ আপনি কেবল থ্রোটল মিডলওয়্যারের সমস্যা থেকে নিজেকে বাঁচিয়েছেন। এটি request()->ip()"TrustProxies" সেট আপ করা বা না ছাড়াই নির্ভর করে , আপনি কেবল সমস্ত অপরাধীর আইপি ব্লক করার পরিবর্তে আপনার সমস্ত ব্যবহারকারীকে লগ ইন করা থেকে আটকাতে পারবেন।

এবং যেহেতু থ্রটল মিডলওয়্যারটি ডকুমেন্টেশনে সঠিকভাবে ব্যাখ্যা করা হয়নি, তাই আমি " শিক্ষানবিশের জন্য লারাভেল 5.2 টিউটোরিয়াল, এপিআই রেট সীমাবদ্ধতা " দেখার পরামর্শ দিই

লারাভেল 5.7 এ পরীক্ষিত


7

লারাভেল 5.4 এ আমরা আইপি স্ট্যাটিক কল করতে পারি না। এটি ব্যবহারকারীর আইপি পাওয়ার সঠিক উপায়:

 use Illuminate\Http\Request;

public function contactUS(Request $request)
    {
        echo $request->ip();
        return view('page.contactUS');
    }

7

আপনি যদি এই ফাংশনটি কল করেন তবে সহজেই আপনি ক্লায়েন্টের আইপি ঠিকানা পাবেন। আমি আমার বিদ্যমান প্রকল্পে এটি ইতিমধ্যে ব্যবহার করেছি:

public function getUserIpAddr(){
       $ipaddress = '';
       if (isset($_SERVER['HTTP_CLIENT_IP']))
           $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
       else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_X_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
       else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_FORWARDED'];
       else if(isset($_SERVER['REMOTE_ADDR']))
           $ipaddress = $_SERVER['REMOTE_ADDR'];
       else
           $ipaddress = 'UNKNOWN';    
       return $ipaddress;
    }

5

আপনি যদি এখনও আইপি হিসাবে 127.0.0.1 পেয়ে থাকেন তবে আপনার নিজের "প্রক্সি" যুক্ত করা দরকার, তবে সচেতন হন যে আপনাকে প্রযোজনায় যাওয়ার আগে এটি পরিবর্তন করতে হবে!

" বিশ্বস্ত প্রক্সি কনফিগার করা " পড়ুন ।

এবং এটি যুক্ত করুন:

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = '*';

এখন request()->ip()আপনাকে সঠিক আইপি দেয়।


4

আপনি যদি ক্লায়েন্ট আইপি চান এবং আপনার সার্ভারটি আউস এলবি এর পিছনে রয়েছে, তবে নিম্নলিখিত কোডটি ব্যবহার করুন। লারাভেল 5.3 এর জন্য পরীক্ষিত

$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();

1
আর কাজ করছে না, এখন "বিশ্বস্তহাইডারসেট"
নিইড

"সাম্প্রতিক" ল্যারাভেল
সান্দ্রা

0

আপনার যদি সিডিএন + লোড ব্যালেন্সারের মতো একাধিক স্তর প্রক্সি থাকে।
লারাভেল অনুরোধ :: আইপি () ফাংশন ব্যবহার করে ডান-সর্বাধিক প্রক্সি আইপি পাবেন তবে ক্লায়েন্ট আইপি নয় IP
আপনি নিম্নলিখিত সমাধান চেষ্টা করতে পারেন।

অ্যাপ্লিকেশন / HTTP / মিডলওয়্যার / TrustProxies.php

protected $proxies = ['0.0.0.0/0'];

তথ্যসূত্র: https://github.com/fideloper/TrustedProxy/issues/107#issuecomment-373065215


0

আমি সেবাস্তিয়ান হরিন ফাংশন getIp এবং অনুরোধ () -> আইপি () (বৈশ্বিক অনুরোধে) ব্যবহার করেছি, কারণ স্থানীয়ভাবে হোস্টপ ফাংশন রিটার্ন নাল:

$this->getIp() ?? request()->ip();

GetIp ফাংশন:

public function getIp(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
    if (array_key_exists($key, $_SERVER) === true){
        foreach (explode(',', $_SERVER[$key]) as $ip){
            $ip = trim($ip); // just to be safe
            if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                return $ip;
            }
        }
    }
}

}



-2
  $ip = $_SERVER['REMOTE_ADDR'];

1
এটি কেন পছন্দের সমাধান এবং এটি কীভাবে কাজ করে তা ব্যাখ্যা করে যদি আপনি কোনও সরবরাহ সরবরাহ করেন তবে এটি আরও সহায়তা করে। আমরা কেবল কোড সরবরাহ না করেই শিক্ষিত করতে চাই। যেমনটি হ'ল, সিস্টেমটি এটি নিম্ন-মানের হিসাবে পতাকাঙ্কিত করছে তাই এটির উন্নতি করার চেষ্টা করুন।
টিন ম্যান

আপনার পরামর্শের জন্য ধন্যবাদ।
রাশেডসেক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.