login.php cho wifi marketing Ruckus

 <?php
function h($s) {
    return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}

function cleanParams(array $input): array {
    $clean = [];

    foreach ($input as $key => $value) {
        $key = preg_replace('/^amp;/', '', (string)$key);
        $clean[$key] = $value;
    }

    return $clean;
}

$params = cleanParams($_POST);

// =======================
// CONFIG
// =======================

$defaultNbiHost = 'thay IP controller vào đây';

$nbiUser = 'nbi-acc';
$nbiPass = 'pass của nbi-acc';

// AAA Always Accept nên user/pass này chỉ là dummy
$ueUsername = 'ok';
$uePassword = 'ok';

// Chỉ cho phép gọi đúng vSZ NBI này
$allowedNbiHosts = [
    'thay IP controller vào đây',
];

// =======================
// INPUT FROM vSZ
// =======================

$nbiHost = $params['nbiIP'] ?? $defaultNbiHost;

if (!in_array($nbiHost, $allowedNbiHosts, true)) {
    $nbiHost = $defaultNbiHost;
}

$nbiUrl = 'https://' . $nbiHost . ':9443/portalintf';

$ueIp    = $params['uip'] ?? '';
$ueMac   = $params['client_mac'] ?? '';
$ueProxy = $params['proxy'] ?? '0';

if ($ueIp === '' || $ueMac === '') {
    http_response_code(400);
    echo 'Missing uip or client_mac';
    exit;
}

// =======================
// BUILD PAYLOAD
// =======================

$payload = [
    'Vendor'          => 'ruckus',
    'APIVersion'      => '1.0',
    'RequestCategory' => 'UserOnlineControl',
    'RequestType'     => 'Login',

    'RequestUserName' => $nbiUser,
    'RequestPassword' => $nbiPass,

    'UE-IP'       => $ueIp,
    'UE-MAC'      => $ueMac,
    'UE-Proxy'    => $ueProxy,
    'UE-Username' => $ueUsername,
    'UE-Password' => $uePassword,
];

// =======================
// CALL vSZ NBI
// =======================

$ch = curl_init($nbiUrl);

curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'Accept: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode($payload, JSON_UNESCAPED_SLASHES),

    // vSZ cert đang expired/self-signed thì để false.
    // Khi thay cert chuẩn có thể bật verify lại.
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,

    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT        => 10,
]);

$response = curl_exec($ch);

$curlNo   = curl_errno($ch);
$curlErr  = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$info     = curl_getinfo($ch);

curl_close($ch);

// =======================
// LOG DEBUG
// =======================

$logPayload = $payload;
$logPayload['RequestPassword'] = '***';

/*
file_put_contents(
    __DIR__ . '/nbi-login.log',
    date('c') .
    ' URL=' . $nbiUrl .
    ' HTTP=' . $httpCode .
    ' CURL_NO=' . $curlNo .
    ' CURL_ERR=' . $curlErr .
    ' INFO=' . json_encode($info, JSON_UNESCAPED_SLASHES) .
    ' PAYLOAD=' . json_encode($logPayload, JSON_UNESCAPED_SLASHES) .
    ' RESPONSE=' . $response .
    PHP_EOL,
    FILE_APPEND
);
*/

// =======================
// CHECK CURL RESULT
// =======================

if ($response === false || $curlNo !== 0 || $curlErr !== '' || $httpCode < 200 || $httpCode >= 300) {
    http_response_code(500);

    echo '<pre>';
    echo "NBI request failed\n";
    echo "HTTP: " . h($httpCode) . "\n";
    echo "CURL_NO: " . h($curlNo) . "\n";
    echo "CURL_ERR: " . h($curlErr) . "\n";
    echo "Response:\n" . h($response) . "\n";
    echo '</pre>';

    exit;
}

$data = json_decode($response, true);

$responseCode = isset($data['ResponseCode']) ? (int)$data['ResponseCode'] : 0;
$replyMessage = $data['ReplyMessage'] ?? '';

// vSZ có thể trả:
// 201 = Login succeeded
// 101 = Client authorized
$successCodes = [101, 201];

if (!in_array($responseCode, $successCodes, true)) {
    http_response_code(500);

    echo '<pre>';
    echo "NBI login not successful\n";
    echo "ResponseCode: " . h($responseCode) . "\n";
    echo "ReplyMessage: " . h($replyMessage) . "\n";
    echo "Full response:\n" . h($response) . "\n";
    echo '</pre>';

    exit;
}

// =======================
// SUCCESS PAGE
// =======================

header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
?>
<!doctype html>
<html lang="vi">
<head>
    <meta charset="utf-8">
    <title>Connected</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        * { box-sizing: border-box; }
        body {
            margin: 0;
            min-height: 100vh;
            font-family: Arial, sans-serif;
            background: #111827;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
        }
        .box {
            width: 90%;
            max-width: 360px;
            background: #ffffff;
            color: #111827;
            padding: 28px;
            border-radius: 16px;
            box-shadow: 0 20px 50px rgba(0,0,0,.35);
        }
        .check {
            width: 64px;
            height: 64px;
            margin: 0 auto 16px;
            border-radius: 50%;
            background: #16a34a;
            color: #ffffff;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 36px;
            font-weight: bold;
        }
        h2 { margin: 0 0 10px; font-size: 24px; }
        p { margin: 0; color: #4b5563; line-height: 1.5; }
        .small { margin-top: 12px; font-size: 12px; color: #6b7280; }
        .dots span {
            animation: bounce 1.2s infinite ease-in-out;
            display: inline-block;
        }
        .dots span:nth-child(2) { animation-delay: 0.2s; }
        .dots span:nth-child(3) { animation-delay: 0.4s; }
        @keyframes bounce {
            0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
            40% { transform: translateY(-5px); opacity: 1; }
        }
        #preload-frame {
            position: absolute;
            width: 1px;
            height: 1px;
            opacity: 0;
            pointer-events: none;
            border: none;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="check">✓</div>
        <h2>Connected</h2>
        <p>Bạn đã kết nối Internet.</p>
        <div class="small dots">Đang chuyển hướng<span>.</span><span>.</span><span>.</span></div>
    </div>

    <iframe id="preload-frame"></iframe>

<script>
    const TARGET = 'https://tamanhhospital.vn/vu-tru-robot/?utm_campaign=bvta_longbien_wifi-sitelongbien_vutrurobot2026_he-thong-may-moc_traffic&utm_source=wifi-sitelongbien&utm_medium=wifi-marketing&utm_content=robot-traffic&utm_term=mass';
    const MIN_DISPLAY_MS = 4000; // minimum time to show this screen

    const start = Date.now();
    let iframeReady = false;
    let timerDone = false;

    function tryRedirect() {
        if (iframeReady || timerDone) {
            window.location.replace(TARGET);
        }
    }

    // Start preloading in hidden iframe
    const frame = document.getElementById('preload-frame');
    frame.src = TARGET;
    frame.onload = function () {
        iframeReady = true;
        tryRedirect();
    };
    frame.onerror = function () {
        // If iframe fails (e.g. X-Frame-Options blocks it), redirect anyway
        iframeReady = true;
        tryRedirect();
    };

    // Minimum display timer
    setTimeout(function () {
        timerDone = true;
        tryRedirect();
    }, MIN_DISPLAY_MS);
</script>
</body>
</html>
<?php
exit;

No comments:

Post a Comment

login.php cho wifi marketing Ruckus

 <?php function h($s) {     return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function cleanParams(array $input): array...