Каталог Поиск 0 Сравнить 0 Закладки 0 Корзина Войти
Каталог
105082, Москва, ул. Фридриха Энгельса, 75с21, БЦ Бауманский ИТКОЛ
Пн - Пт: с 09-00 до 18-00 Сб: с 10-00 до 18-00 Вс: выходной
Страницы: 1
RSS
Скрипт авторизации на PHP работает нормально, но клиент не отображается как авторизованный., UniFi Network
 
Я на начальном этапе разработки внешнего портала для входа в Wi-Fi. Использую следующий скрипт для авторизации устройства, которое уже подключено к точке доступа:

<?php  
$id = "x2:ff:ff:ff:ff:ff"; // Замените на MAC подключенного устройства  
$minutes = 480;  
$key = 12345;  

function sendAuthorization($id, $minutes) {  
   $unifiServer = "https://localhost:8443";  
   $unifiUser = "admin";  
   $unifiPass = "password";  

   // Запуск Curl для входа  
   $ch = curl_init();  
   // Отправляем данные методом POST  
   curl_setopt($ch, CURLOPT_POST, TRUE);  
   // Работа с куками  
   $cookie_file = "/tmp/unifi_cookie";  
   curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);  
   curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);  
   // Разрешаем самоподписанные сертификаты  
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
   curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);  
   // Принудительно SSL3  
   curl_setopt($ch, CURLOPT_SSLVERSION, 1);  
   // Логинимся на UniFi контроллер  
   curl_setopt($ch, CURLOPT_URL, "$unifiServer/login");  
   curl_setopt($ch, CURLOPT_POSTFIELDS, "login=login&username=$unifiUser&password=$unifiPass");  
   curl_exec($ch);  

   // Отправляем команду авторизации пользователя и время доступа  
   $data = json_encode(array(  
       'cmd' => 'authorize-guest',  
       'mac' => $id,  
       'minutes' => $minutes  
   ));  

   // Отправляем команду на API  
   curl_setopt($ch, CURLOPT_URL, $unifiServer.'/api/s/default/cmd/stamgr');  
   curl_setopt($ch, CURLOPT_POSTFIELDS, 'json='.$data);  
   curl_exec($ch);  

   // Выходим из UniFi контроллера  
   curl_setopt($ch, CURLOPT_URL, $unifiServer.'/logout');  
   curl_exec($ch);  
   curl_close($ch);  
   unset($ch);  
}  

if ($key == "12345") { // Проверяем, отправлена ли форма  
   ob_start();  
   sendAuthorization($id, $minutes);  
   ob_end_clean();  
   unset($key);  
}  
?>

Подключение к сети...

<script>  
// даём время на завершение авторизации  
setTimeout("location.href='http://www.google.com'", 6000);  
</script>

Скрипт вроде бы работает, но когда я захожу в контроллер и смотрю список клиентов, устройство всё ещё отображается как неавторизованное. Версия контроллера 4.7.6.  
Обратил внимание, что файл куки не создаётся. Права доступа в порядке, проверял с другим скриптом — файл создаётся.  
Есть идеи, в чём может быть проблема?
 
Похоже, что то, что я сделал, помогло. Буду наблюдать несколько дней. Огромное спасибо @slooffmaster
 
Хм, не понимаю, почему у тебя все еще эта проблема. Не могу представить, что настройки IP могут вызывать это, но если возможно, не помешает сбросить AP до заводских настроек и заново их подключить. Спасибо за совет по поводу функции одного устройства и за подтверждение, что она используется. Это уже было в моем списке изменений для класса как опциональный параметр, но я не был уверен, что кому-то это нужно или кто-то будет этим пользоваться.
 
Спасибо, попробую.
 
Вижу, что вы не отправляете MAC-адрес точки доступа вместе с запросом на авторизацию. Обычно это не обязательно, но в некоторых случаях может замедлять процесс. Честно говоря, сложно понять, что здесь происходит. Могу предложить упростить ваш код до пары строк, используя этот класс API-клиента: https://github.com/malle-pietje/Unifi-API-browser/blob/master/phpapi/class.unifi.php

Следующий код — это практически всё, что нужно для вызова API:
// подключаем класс для соединения с Unifi
include('phpapi/class.unifi.php');
// создаём экземпляр класса
$unifi = new unifiapi($user_name, $password, $url, $site_id, $version);
// выполняем вход
$unifi->login();
// запрашиваем авторизацию...
$result = $unifi->authorize_guest($mac_address, $auth_duration, $up, $down, $data, $ap_mac_address);
// и на этом всё

Этот класс настроен немного иначе, чем ваши вызовы через curl, так что, возможно, попробовать стоит — хуже точно не будет. Класс отлично работает "из коробки".
 
Вот php-код:

```php
$usermac = $_GET['usermac'];
if (!preg_match('/^([a-f0-9]{2}:){5}[a-f0-9]{2}$/ims', $usermac)) {
   die();
}
$ip = $_SERVER['REMOTE_ADDR'];
file_put_contents('log.txt', array(date('r'), " ", $usermac, " ", $ip), FILE_APPEND);

// НОВАЯ СХЕМА
$USERNAME = 'autoapi';
$PASSWORD = 'r';
$COOKIEFILE = 'cookie.txt';

$cookie = "cookie.txt";

$data = array("username" => $USERNAME, "password" => $PASSWORD);
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
//curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.91 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);

curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_URL, 'https://10.200.201.146:8443/api/login');
$data = curl_exec($ch);

file_put_contents('log.txt', "UNIFIlogin:" . $data, FILE_APPEND);

$user_mac = $usermac;
$data = array("cmd" => "authorize-guest", "mac" => $user_mac, "minutes" => "120");
$data_string = json_encode($data);

$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
//curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.91 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
   'Content-Type: application/json',
   'Content-Length: ' . strlen($data_string))
);
curl_setopt($ch, CURLOPT_URL, 'https://10.200.201.146:8443/api/s/default/cmd/stamgr');
$data = curl_exec($ch);
file_put_contents('log.txt', "AUTHmac:" . $data, FILE_APPEND);
$data = json_decode($data);

print "1";
file_put_contents('log.txt', "\n", FILE_APPEND);
?>
```
 
Странно, что иногда в ответе отсутствует ap-mac... Какой именно код ты используешь для авторизации клиентов и логируешь ли команды, которые отправляются в API контроллера? Кстати, чтобы сэкономить время на поддержку, можешь просто использовать мой класс API-клиента: https://github.com/malle-pietje/Unifi-API-browser/blob/master/phpapi/class.unifi.php
 
Это контроллер версии 4.8.14, прошивка AP — BZ.v3.3.19. Мы используем внешний портал. На гостевой кнопке и в captive portal с php-скриптом через curl пытаемся авторизовать гостя. Команды "login" и "authorize-guest". Я логирую все ответы контроллера в файл, и контроллер всегда отвечает OK, например так:  
{ "data" : [ { "_id" : "570df5dec01c8812eb194102" , "ap_mac" : "dc:9f:db:b0:3e:0d" , "authorized_by" : "api", "end" : 1460539936 , "mac" : "a4:c3:61:45:30:d0" , "site_id" : "5236b42ac01c8fae5a5ad2b4" , "start" : 1460532702}] , "meta" : { "rc" : "ok"}}
Но иногда в ответе отсутствует "ap_mac", например так:  
{ "data" : [ { "_id" : "570df003c01c8812eb193abb" , "authorized_by" : "api" , "end" : 1460538410 , "mac" : "cc:fa:00:b6:9a:2b" , "site_id" : "5236b42ac01c8fae5a5ad2b4" , "start" : 1460531203}] , "meta" : { "rc" : "ok"}}
Скриншот ui-лога во вложении. Там есть сообщения, похожие на логи сервера.
 
Хорошо, может, вы предоставите больше деталей? Какой captive portal вы используете (встроенный контроллер или внешний), и если внешний — каким именно образом вы запрашиваете авторизацию клиента через контроллер? Также, что содержится в журнале событий вашего контроллера в интерфейсе примерно в то время, когда вы запрашиваете авторизацию?
 
Пытаюсь проанализировать трафик с AP на контроллер. Это HTTP-приложение с протоколом X-binary между процессом mcad на AP и портом 8080 на контроллере. В общем, я отключил брандмауэр Windows, но проблема осталась.
 
На самом деле связь между AP и контроллером работает как раз наоборот: именно AP подключаются к контроллеру, а не наоборот (в большинстве случаев это даже невозможно, особенно если контроллер запущен где-то в облаке...). Для моего тестового сервера на AWS я настроил следующие «правила брандмауэра»/«группы безопасности»:
 
Отключение брандмауэра Windows не повлияло на эту проблему.
 
Спасибо за ответ! Контроллер работает на Windows. Я дал все разрешения для процесса java в брандмауэре Windows. Иначе все точки доступа были бы «Отключены», верно? Какие порты использует unifi для связи с точками доступа? P.S. Я отключу брандмауэр Windows и посмотрю логи.
 
Не могли бы вы уточнить, какие именно порты вы открыли (в файерволе сервера или где-то ещё), чтобы ваши точки доступа могли получить доступ к контроллеру?
 
Похоже, что у автора темы проблемы с авторизацией в контроллере. Но у нас другая проблема. Точка доступа не сообщила контроллеру о каком-то гостевом MAC-адресе, а потом контроллер не сообщил точке доступа, что гостевой MAC-адрес был авторизован.
 
У меня такая же проблема.
 
Как вы решили свою проблему? Я тоже с этим мучаюсь. В моём внешнем гостевом портале всё вроде нормально, пока не доходит до функции sendAuthorization(). А дальше — провал в чёрную дыру...
Страницы: 1
Читают тему (гостей: 1)