API and Code Sample for External Portal Server (Omada Controller 2.6.0 to 3.2.17)
Suitable for Omada Controller 2.6.0 to 3.2.17.
For Omada Controller below 2.5.4 or below, please refer to FAQ928
For Omada Controller 4.1.5 to 4.4.6, please refer to FAQ2907
For Omada Controller 5.0.15 or above, please refer to FAQ3231
This document outlines the requirements when establishing an external portal server. For how to configure External Portal Server, please refer to FAQ-896 (step 2 of section 5)
The below picture depicts the data flow among wireless client, EAP device, Omada Controller, portal server and authentication server which may help you to better understand the requirements of establishing an external portal server.
1. Wireless client is connected to the SSID on which portal authentication is enabled and tries to access the Internet. EAP device will intercept client’s HTTP request and then redirect it to the Omada Controller. The client will then send GET request to the Omada Controller with query string “cid=client_mac&ap=ap_mac&ssid=ssid_name&t=time_since_epoch&rid=Radio_id” in the URL according to the HTTP response it receives from the EAP. (Step 1 and Step 2)
2. The Omada Controller then redirects the client to the external portal server by replying a HTTP response with status code 302 Found to the client. The HTTP response with this status code will additionally provide the URL of external portal server in the location field. The URL also contains the query string. For Omada Controller 2.6.0 or above the URL is http://portal_server_ip?cid=client_mac&ap=ap_mac&ssid=ssid_name&t=time_since_epoch&rid=Radio_id&site=site_name. (Step 3 and Step 4)
The meaning of the parameters is listed in Table 1 Parameter explanation.
3. The client will send GET request to external portal server using the URL which is mentioned above.(Step 5)
4. External portal server must be able to intercept and keep a record of the parameters in the query string of the GET request and return a web page with authentication form to the wireless client. (Step 6)
5. The wireless client’s authentication information will be submitted to the portal server, and the portal server will submit the information to the authentication server (Step 7 and Step 8). However, how portal server gets client’s authentication information and how portal server communicates with authentication server depend on your own implementation which is out of the scope of this article.
6. The authentication server verifies the authentication information and return the result to the portal server. (Step 9)
NOTE: In this example the portal server and the authentication server are separated. But they can be installed on the same server as you wish. The authentication method is also up to you. Just make sure the portal server knows when the authentication is passed.
7. If the authentication succeeds, the portal server should send the client information to the Omada Controller by calling the API of the Omada Controller. First, it must login the Omada Controller by sending a POST request. The request’s URL will be https://controller_server_ip:https_port/login and it will carry the data “name=the_username_of_controller&password=the_password_of_controller” using JSON format in the HTTP message body.
For example,
private static function login()
{
$ch = curl_init();
// post
curl_setopt($ch, CURLOPT_POST, TRUE);
// Set return to a value, not return to page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set up cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, COOKIE_FILE_PATH);
curl_setopt($ch, CURLOPT_COOKIEFILE, COOKIE_FILE_PATH);
// Allow Self Signed Certs
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// API Call
curl_setopt($ch, CURLOPT_URL, CONTROLLER_SERVER . "/login");
curl_setopt($ch, CURLOPT_POSTFIELDS, "name=" . CONTROLLER_USER ."&password=" . CONTROLLER_PASSWORD);
$res = curl_exec($ch);
$resObj = json_decode($res);
// Prevent CSRF
if($resObj->success == true){
self::setCSRFToken($resObj->value);
}
curl_close($ch);
}
private static function setCSRFToken($token){
$myfile = fopen(TOKEN_FILE_PATH, "w") or die("Unable to open file!");
fwrite($myfile, $token);
fclose($myfile);
return $token;
}
(Step 10)
8. If the portal sever has logged in the controller successfully, it will then send the client information to https://controller_server_ip:https_port/extportal/site_name/auth?token=CSRFToken using POST method. The information data can be represented by JSON farmat and must contain these parameters “cid=client_mac&ap=ap_mac&ssid=ssid_name&t=time_since_epoch&rid=Radio_id&site=site_name&time=expire_time”.
For example,
private static function authorize($cid,$ap,$ssid,$rid,$t,$seconds,$site)
{
// Send user to authorize and the time allowed
$authInfo = array(
'cid' => $cid,
'ap' => $ap,
'ssid' => $ssid,
'rid' => $rid,
't' => $t,
'time' => $seconds
);
$ch = curl_init();
// post
curl_setopt($ch, CURLOPT_POST, TRUE);
// Set return to a value, not return to page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set up cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, COOKIE_FILE_PATH);
curl_setopt($ch, CURLOPT_COOKIEFILE, COOKIE_FILE_PATH);
// Allow Self Signed Certs
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// API Call
$csrfToken = self::getCSRFToken();
curl_setopt($ch, CURLOPT_URL, CONTROLLER_SERVER ."/extportal/". $site."/auth"."?token=".$csrfToken);
$data = json_encode($authInfo);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($authInfo));
$res = curl_exec($ch);
$resObj = self::resultConvert($res);
if($resObj['success'] == false){
echo $res;
}
curl_close($ch);
}
private static function resultConvert($json)
{
$json = str_replace(array('{','}',':',','),array('[{" ',' }]','":',',"'),$json);
function cb_quote($v)
{
return '"'.trim($v[1]).'"';
}
$newJSON=preg_replace_callback("~\"(.*?)\"~","cb_quote", $json);
$res = json_decode($newJSON, true)[0];
return $res;
}
private static function getCSRFToken(){
$myfile = fopen(TOKEN_FILE_PATH, "r") or die("Unable to open file!");
$token = fgets($myfile);
fclose($myfile);
return $token;
}
(Step 11)
The meaning of these parameters is the same as in Table 1 Parameter explanation. The time parameter here is the number of seconds before client authentication expires. This parameter is defined by the portal server.
9. The Omada Controller returns a JSON message: {"success": [true/false], "message":" return information"} to the portal server after the Omada Controller has dealt with the information provided in the HTTP POST request. How the portal server deals with the JSON message depends on your own implementation. At last the portal sever must logout the Omada Controller by sending a POST request to https://controller_server_ip:https_port/logout?token=CSRFToken.
For example
private static function logout()
{
$ch = curl_init();
// Post
curl_setopt($ch, CURLOPT_POST, TRUE);
// Set return to a value, not return to page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set up cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, COOKIE_FILE_PATH);
curl_setopt($ch, CURLOPT_COOKIEFILE, COOKIE_FILE_PATH);
// Allow Self Signed Certs
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// API Call
$csrfToken = self::getCSRFToken();
curl_setopt($ch, CURLOPT_URL, CONTROLLER_SERVER . "/logout"."?token=".$csrfToken);
curl_exec($ch);
curl_close($ch);
}
(Step 12 and Step 13)
TOKEN_FILE_PATH is a file that save the CSRFToken returned from login request, customers can configure it themselves.
Note: For calling the API successfully, your portal server should be configured to achieve the following two points:
1. Allow self-signed certificate;
2. Read the server https packet, save the TPEAP_SESSIONID in Cookie,request with this cookie in the future.
Is this faq useful?
Your feedback helps improve this site.
TP-Link Community
Still need help? Search for answers, ask questions, and get help from TP-Link experts and other users around the world.