在
PHP笔记-用户登录&权限拦截说明
这篇博文中设置Cookie时用的是数据库的用户id。这样有问题,用户可以随意改动ID,从而获取不同的用户权限。
这里我们更新下,增加点安全性。构造safe包
内容如下:
CookieAndSession.php
<?phpnamespace safe;class CookieAndSession{public $cookie;public $userId;public $browser;public $os;public $timeToLive;}
CookieTool.php
<?phpnamespace safe;class CookieTool{protected function generateKey(): string{$length = 32;$retKey = "";for ($i = 0; $i < $length; $i++){$retKey .= chr(mt_rand(33, 126));}return $retKey;}protected function getIPAddress(): string{$ipaddress = "";if (isset($_SERVER['HTTP_CLIENT_IP']))$ipaddress = $_SERVER['HTTP_CLIENT_IP'];else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];else if(isset($_SERVER['HTTP_X_FORWARDED']))$ipaddress = $_SERVER['HTTP_X_FORWARDED'];else if(isset($_SERVER['HTTP_FORWARDED_FOR']))$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];else if(isset($_SERVER['HTTP_FORWARDED']))$ipaddress = $_SERVER['HTTP_FORWARDED'];else if(isset($_SERVER['REMOTE_ADDR']))$ipaddress = $_SERVER['REMOTE_ADDR'];else$ipaddress = 'UNKNOWN';return $ipaddress;}protected function getBrowser($agent): string{$browserAgent = "";if(strstr($agent, 'MSIE')) {$browserAgent="Internet Explorer";}else if(strstr($agent, 'Opera')) {$browserAgent="Opera";}else if(strstr($agent, 'Firefox')) {$browserAgent="Firefox";}else if(strstr($agent, 'Chrome')) {$browserAgent = "Chrome";}else if(strstr($agent, 'Safari')) {$browserAgent = "Safari";}else{$browserAgent = "unknown";}return $browserAgent;}protected function getPlatform($agent): string{$agent = strtolower($agent);$platform = "";if(strstr($agent, 'win')) {$platform="windows";}else if(strstr($agent, 'linux')) {$platform = "linux";}else{$platform = "unknown";}return $platform;}protected function getMacAddress(): string{$MAC = exec('getmac');print_r($MAC);$MAC = strtok($MAC, ' ');return $MAC;}public function printCookieArray(){global $cookieAndSessionArray;print_r($cookieAndSessionArray);}public function setCookieByUserId($userId){$userToken = $this->generateKey();$browserAgent = $this->getBrowser($_SERVER['HTTP_USER_AGENT']);$platform = $this->getPlatform($_SERVER['HTTP_USER_AGENT']);$cookieAndSession = new CookieAndSession();$cookieAndSession->cookie = $userToken;$cookieAndSession->userId = $userId;$cookieAndSession->browser = $browserAgent;$cookieAndSession->os = $platform;$cookieAndSession->timeToLive = 24 * 60 * 60;@session_start();$_SESSION["user"] = serialize($cookieAndSession);setcookie('userToken',$userToken ,time() + 1 * 24 * 3600);}}
因为这里我用的是自定义MVC框架,在每次加载的时候,会调用如下start函数:
public static function start(){self::setPath();self::setConfig();self::setSafe();self::setUrl();self::setAutoLoad();self::setDispatch();}
其中setSafe()就是新加的,作用是加载对应的php文件
private static function setSafe(){$files = self::getAllFile(SAFE_PATH);foreach($files as $file){if(file_exists($file)){include $file;}}}
其中getAllfile是获取当前目录下的所有文件,如下:
private static function getAllFile($dir): array{$retArray = array();if(!is_dir($dir))return $retArray;$files = scandir($dir);foreach ($files as $file){$tmpFile = $dir . "/" . $file;if(!is_dir($tmpFile)){array_push($retArray, $dir . "/" . $file);}}return $retArray;}
其中SAFE_PATH如下:
ROOT_PATH在index.php中定义的,如下:
index.php
<?phpdefine("ROOT_PATH", str_replace("\\", "/", dirname(__DIR__)) . "/");include ROOT_PATH . "core/App.php";\core\App::start();
当用户点击登录后:
其userToken就为随机数了
后台登录校验是这样的:
public function check(){$useName = trim($_POST["userName"]);$password = trim($_POST["password"]);$captcha = trim($_POST["captcha"]);..................$cookieTool = new CookieTool();$cookieTool->setCookieByUserId($user['user_id']);$this->success("登录成功", '', 'dashboard', "index");}
权限拦截如下:
public function __construct(){include VENDOR_PATH . "smarty/Smarty.class.php";$this->smarty = new \Smarty();$this->smarty->template_dir = APP_PATH . P . "/view/";$this->smarty->compile_dir = RESOURCES_PATH . "views";if(strtolower(C) != "privilege"){if(isset($_COOKIE['userToken'])){@session_start();$obj = unserialize($_SESSION["user"]);if(strcmp($_COOKIE['userToken'], $obj->cookie) != 0){$this->error("未登录,请先登录", "user", "privilege", "login");}$userModel = new UserModel();$user = $userModel->getById((int)$obj->userId);if($user){return;}}$this->error("未登录,请先登录", "user", "privilege", "login");}}