主要設置鑑權服務器主機名(域名或ip均可以)和加粗鑑權服務器路徑php
路由器會請求如下四個地址:html
http://認證服務器/路徑/login
http://認證服務器/路徑/auth
http://認證服務器/路徑/ping
http://認證服務器/路徑/portal
http://認證服務器/路徑/gw_message.phpmysql
因此咱們須要每一個請求創建一個文件夾下一個index.phpsql
客戶端首次鏈接wifi,瀏覽器請求將被重定向到login並攜帶參數數據庫
login/?gw_address=路由器ip&gw_port=路由器wifidog的端口&gw_id=用戶id&url=被重定向前用戶瀏覽的地址segmentfault
(2013版本的wifidog參數多了mac)瀏覽器
而login/index.php須要作的就是驗證經過後再重定向到網關:服務器
http://網關地址:網關端口/wifidog/auth?token=session
以後wifidog會啓動一個線程週期性報告用戶狀態:post
/auth?stage=&ip=&mac=&token=&incoming=&outgoing=
/auth/index.php則須要返回是否讓該用戶繼續上網,回覆格式:Auth:狀態碼(0:拒絕, 1:驗證經過)
驗證成功後,路由器將請求/portal/?gw_id=%s
在/portal/index.php就能夠寫重定向到第一次請求的url參數或者重定向到自定義網址了
/ping/index.php的做用就是告訴路由器認證服務器尚未崩
/gw_message/index.php做用是當認證過程出現錯誤的時候,想用戶顯示錯誤信息
咱們將完成用戶用帳號密碼方式認證
/login/index.php
<?php //獲取url傳遞過來的參數 parse_str($_SERVER['QUERY_STRING'], $parseUrl); //gw_address、gw_port、gw_id是必需參數,缺乏不能認證成功. if( !array_key_exists('gw_address', $parseUrl) || !array_key_exists('gw_port', $parseUrl) || !array_key_exists('gw_id', $parseUrl)){ exit; } //若是提交了帳號密碼 if(isset($_POST['name']) && isset($_POST['password'])){ $username = $_POST['name']; $password = $_POST['password']; $db = new mysqli('localhost', 'root', '', 'test'); if(mysqli_connect_errno()){ echo mysqli_connect_error(); die; } $db->query("set names 'utf8'"); $result = $db->query("SELECT * FROM user WHERE username='{$username}' AND password='{$password}'"); if($result && $result->num_rows != 0){ //數據庫驗證成功 $token = ''; $pattern="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ"; for($i=0;$i<32;$i++) $token .= $pattern[ rand(0,35) ]; //把token放到數據庫,用於後續驗證(auth/index.php) $time = time(); $sql = "UPDATE user SET token='{$token}',logintime='{$time}'"; $db->query($sql); $db->close(); //登錄成功,跳轉到路由網管指定的頁面. $url = "http://{$parseUrl['gw_address']}:{$parseUrl['gw_port']}/wifidog/auth?token={$token}"; header("Location: ".$url); }else{ //認證失敗 //直接重定向本頁 請求變成get $url='http://'.$_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"]; header("Location: ".$url); } }else{ //get請求 //一個簡單的表單頁面 $html = <<< EOD <html> <head> <title>portal login</title> </head> <body> <form action="#" method="post"> username:<input type="text" name="username" /> password:<input type="password" name="password" /> <input type="submit" value="submit" /> </form> </body> </html> EOD; echo $html; }
/auth/?stage=%s&ip=%s&mac=%s&token=%s&incoming=%s&outgoing=%s
參數解釋:
stage: 認證階段,就logoin和counters兩種
token: login頁面下發的token
incoming: 下載流量
outgoing: 上傳流量
/auth/index.php
<?php //獲取url傳遞過來的參數 parse_str($_SERVER['QUERY_STRING'], $parseUrl); //須要多少參數用戶可本身頂 if( !array_key_exists('token', $parseUrl) ){ //拒絕 echo "Auth:0"; exit; } $db = new mysqli('localhost', 'root', '', 'test'); $db->query("set names 'utf8'"); $token = $parseUrl['token']; $sql = "SELECT * FROM user WHERE token='{$token}'"; $result = $db->query($sql); if($result && $result->num_rows != 0){ //token匹配,驗證經過 echo "Auth:1"; }else{ echo "Auth:0"; }
/ping/?gw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu
wifidog會向認證服務器發送一些信息,來報告wifidog如今的狀況,這些信息是經過Http協議發送的,如上的連接所示,參數大概如字面意思,沒仔細研究過,而做爲認證服務器,auth_server應迴應一個"Pong"。
主要做用是路由確認認證服務器仍然存活,沒有死機,另一個功能是認證服務器能夠收集路由的負載等的信息。路由器會定時訪問這個腳本,腳本必須回覆Pong,不然將認爲認證服務器失效而出錯。
/ping/index.php
<?php echo "Pong"; ?>
portal/?gw_id=%s
在認證成功後,wifidog會將用戶重定向至該頁面。
/portal/index.php
<?php //認證前用戶訪問任意url,而後被重定向登陸頁面,session記錄的是這個「任意url」. $url = $_SESSION["url"];//若是login參數url保存到session中 //跳轉到登錄前頁面. header("Location: ".$url);
gw_message.php?message=denied
gw_message.php?message=activate
gw_message.php?message=failed_validation
/gw_message.php
<?php $message = null; if(isset($_GET["message"])){ $message = $_GET["message"]; } echo $message; ?>
wifidog的認證流程是:
用戶連上wifi,發起一個訪問網站的請求,如:segmentfault.com
網關根據防火牆規則,將請求重定向本地(路由器的ip)的wifidog端口
wifidog重定向到認證服務器的認證頁面
認證服務器返回登陸頁面讓用戶填寫
用戶填寫後請求認證
認證服務器根據用戶提供數據肯定是否符合要求
若是符合要求,認證服務器將用戶重定向路由器網關並攜帶token
網關向認證服務器肯定用戶信息
若是符合要求,服務器返回用戶登陸成功的頁面
用戶正常上網