有時候你的網站賬號被盜或你在別處登錄操作后台時,右下角會彈出提示信息,提醒你的賬號異地登錄,或者會被強制下線。對於這種安全性要求比較高的web網站,很多后台管理都會做這種功能提醒。
甄別自己的賬號是否被盜或者是否有另一個人此刻登陸了在進行后台操作,這些都是很不安全的,為了避免兩個人同時登錄同時操作,可強制下線一個賬號。我們今天就來講解這個知識點。
當然,通過IP判斷是不行的,因為IP是隨時會在某一個網段內變化的,不過有一個機制,那就是session,恰巧可以解決這個,只要你使用同一個瀏覽器訪問網站,瀏覽器不關閉每個來訪者的session_id是不變的,這也正是解決這個問題需要的。
以TP5.0框架搭建的網站后台為例;用哪各框架都一樣
(1)修改數據庫用戶表
在user表中,增加一個字段`session_id` varchar(32),用來存放登錄之后的session_id。
(2)用戶登錄
用戶登錄,就是正常的判斷賬號密碼以及驗證碼,當這些都驗證通過的時候,取出當前的session_id存入數據庫user表中。
(3)解決異地登錄問題 對於后台操作,為了便於驗證和操作安全,基本都會先創建一個公共控制器Common去繼承控制器基類,然后后台的其他操作控制器都繼承這個公共控制器。對於后台的每一步操作之前,用戶狀態的檢測都放在Common控制器的__construct構造方法中。
現在在__construct構造方法中,除了驗證用戶登錄狀態是否被鎖定等等,還要取出本地session_id和存放在admin表中的session_id進行比對,如果對不上那么表名賬號在異地有登陸,這時候可以迫使強制下線,退回到登錄頁面。代碼如下:
$user=Db::name('admin')->where('id',session('admin_id'))->find(); $session_id = session_id(); if($user['session_id'] != $session_id){ session_destroy(); $this->error('登錄異常,被迫下線', 'Login/index'); }
效果如下:
Login.php核心代碼,isGet就顯示登錄頁面,不是就進行登錄處理操作。
class Login extends Common { public $is_check_login = false; public function index(){ if($this->request->isGet()){ return $this->fetch(); } //調用自定義的方法實現登錄 $model = model('Admin'); $result = $model->login(); if($result === false){ $this->error($model->getError()); } } }
Admin.php,主要是處理上面login的邏輯與處理方法。校驗等,不返回false就存入session_id
Common.php公共控制器文件,login繼承公共方法,也就是中間件。意味着登錄之前優先通過公共方法,此處接收session_id與存在表里的session_id是否一致,不一致就提醒異地登錄,強制下線!
public $is_check_login=true; public $request; public function __contruct(Request $req) { parent::__contruct(); $this->request =$req; if(!session('admin_id') && $this->is_check_login){ $this->error("先去登錄",'Login/index'); } if(session('admin_id') && $this->is_check_login){ $user = "select...." //查找存在表里的session_id,然后作比較 if(session('admin_id') != $user['session_id']){ session_destroy(); $this->error("登錄異常,被迫下線"); } } }
整個過程思路是不是很清晰呀,所以實現起來,你也就覺得很簡單咯!其實就是在講sesson_id的一個用法!