Check if an IP Belongs to a Private Subnet in Laravel 10

Trong Laravel ta có thể check được ip , chính vì thế giúp ta có thể hạn chế được các ip không cho phép vào website hoặc không được phép vào một số route 

Để làm được điều đó, ta có thể thông qua Middleware để check tất cả các request vào website , dưới đây là một cách ta có thể cấu hình như sau:

# Tạo Middleware

 php artisan make:middleware CheckIpMiddleware

Sau khi tạo xong ta cần cấu hình tệp middleware trên như sau:

use Symfony\Component\HttpFoundation\IpUtils;

class CheckIpMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $ip = $request->ip();
        $isPrivate = IpUtils::isPrivateIp($ip);
        if (!$isPrivate) {
            return response('Unauthorized.id.'.$ip, 401);
        }
        return $next($request);
    }
}

 

# Đăng ký Middleware 

Ở đây mình dùng Laravel version 11, nên mình vào app/bootstrap/app.php 

<?php
.....
// 🚀 Chúng ta cần khai báo tệp middleware
use App\Http\Middleware\CheckIpMiddleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {

        // 💪 Hãy thêm các Middleware của ta ở đây
        $middleware->append(CheckIpMiddleware::class);

    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

 

# Sử dụng Middleware

Giả sử ta có các đường dẫn trong web.php, tất cả các request điều chạy qua Middleware CheckIPMiddleware, này trước

Danh sách ip: https://github.com/symfony/symfony/blob/6.3/src/Symfony/Component/HttpFoundation/IpUtils.php

public const PRIVATE_SUBNETS = [
        '127.0.0.0/8',    // RFC1700 (Loopback)
        '10.0.0.0/8',     // RFC1918
        '192.168.0.0/16', // RFC1918
        '172.16.0.0/12',  // RFC1918
        '169.254.0.0/16', // RFC3927
        '0.0.0.0/8',      // RFC5735
        '240.0.0.0/4',    // RFC1112
        '::1/128',        // Loopback
        'fc00::/7',       // Unique Local Address
        'fe80::/10',      // Link Local Address
        '::ffff:0:0/96',  // IPv4 translations
        '::/128',         // Unspecified address
    ];
Route::get('/stream', function () {

    // ✅  Chỉ chấp nhận dữ liệu dạng "json"
    $responseJson = Http::acceptJson()->get('https://dummyjson.com/products')['products'];

    // 📌 Cài đặt StreamedResponse để trả dữ liệu về từng phần
    // ✅  Sử dụng khi dữ liệu trả về số lượng lớn
    $response = new StreamedResponse(function () use ($responseJson) {
        foreach ($responseJson as $key => $value) {
            echo json_encode($value) . "\n";
        }
    }, 200, [
        'Content-Type' => 'application/json',
    ]);

    // 😁 return full data json
    // return $responseJson;

    return $response;

});

 

// Laravel tip ✅
// 🖍 Khai báo lớp IpUtils
use Symfony\Component\HttpFoundation\IpUtils;

Route::get('/check-ip', function () {

    // 👉 lấy IP của người dùng
    $ipv4 =  request()->ip();

    // 😀 kiểm tra ip được phép hay không
    $isPrivate_ipv4 = IpUtils::isPrivateIp($ipv4);

    // ví dụ ipv6
    $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f';
    $isPrivate_ipv6 = IpUtils::isPrivateIp($ipv6);

    return Response()->json(['private' => $isPrivate_ipv4, 'private_ipv6' => $isPrivate_ipv6]);
});

 


Route::get("/admin/dashboard", function () {
    return Response()->json(["success"=>true,"message"=>"Welcome to dashboard"]);
});

 

Bài Viết Liên Quan

Messsage

Nếu bạn thích chia sẻ của tôi, đừng quên nhấn nút !ĐĂNG KÝ