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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,关于Android登录后台实现APP登录功能,你需要进行以下步骤: 1.在Android项目中添加网络权限 在AndroidManifest.xml文件中添加以下代码: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 2.使用HttpURLConnection发送POST请求 可以使用HttpURLConnection类来发送POST请求,以下是一个示例代码: ```java URL url = new URL("http://yourbackend.com/login"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoInput(true); conn.setDoOutput(true); //添加请求头 conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); //添加请求体 JSONObject jsonParam = new JSONObject(); jsonParam.put("username", "yourusername"); jsonParam.put("password", "yourpassword"); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(jsonParam.toString()); writer.flush(); //读取响应 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } reader.close(); String response = sb.toString(); ``` 3.解析后台返回的数据 在上面的代码中,我们使用了JSONObject类来创建一个JSON请求体。在得到后台返回的数据后,你需要使用相应的JSON解析器来解析返回的数据。例如,可以使用GSON库来解析JSON数据: ```java Gson gson = new Gson(); LoginResponse response = gson.fromJson(sb.toString(), LoginResponse.class); ``` 其中,LoginResponse是一个你自己定义的Java类,用来表示后台返回的数据。你需要根据后台返回的数据来定义这个类的属性。 以上就是实现Android登录后台的基本步骤,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值