PHP笔记-随机生成cookie后台检索通过session获取ID增强安全性

Posted IT1995

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP笔记-随机生成cookie后台检索通过session获取ID增强安全性相关的知识,希望对你有一定的参考价值。

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");
        
    

以上是关于PHP笔记-随机生成cookie后台检索通过session获取ID增强安全性的主要内容,如果未能解决你的问题,请参考以下文章

向后台提交数据:利用cookie加session提交更多数据,

php学习笔记-超级全局变量

如何从 Amazon SES 检索响应?

PHP学习笔记:万能随机字符串生成函数(已经封装好)

nodejs怎么生成3rdsession

php学习笔记-会话控制简单介绍session和cookie