在
PHP笔记-用户登录&权限拦截说明
这篇博文中设置Cookie时用的是数据库的用户id。这样有问题,用户可以随意改动ID,从而获取不同的用户权限。

这里我们更新下,增加点安全性。构造safe包

内容如下:
CookieAndSession.php
- <?php
-
- namespace safe;
-
- class CookieAndSession{
-
- public $cookie;
- public $userId;
- public $browser;
- public $os;
- public $timeToLive;
- }
CookieTool.php
- <?php
-
- namespace 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
- <?php
-
- define("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");
- }
- }



















