【问题标题】:Looking for inputs on my cookie/session authentication class, not sure if i got it correct在我的 cookie/会话身份验证类上寻找输入,不确定我是否正确
【发布时间】:2011-11-20 03:24:39
【问题描述】:

我目前正在为我的网站创建自己的论坛,我已经阅读了大量关于 cookie/会话身份验证的主题,我认为我知道存在的攻击等。我知道它不是 100% 安全的,但我试图尽可能安全。

我目前将 IP 存储在 cookie 中,并且我知道有些人可能对此有问题,但我将改为检查 IP 的前 2 个块。我不认为这会是一个问题,因为瑞典 95% 的人都有宽带,很少改变 IP。

我真正不安全的事情是 session_start ,我稍后确实需要表单等什么是实现它的最佳实践?我很确定我做那件事非常错误。

非常感谢任何输入!

class user2
{
    private $db = null;
    private $cookie_salt = '!!PLonSIMDSAM35324dfg5DAUSHODNASDJ353NMASDSA&%&A/SD&HASNJDdfghAS&DGIHYAUSDNA3535SDFASDF%A3532dfgsdfggsdg53532535SDGIASYDU';

    var $user_ip = false;
    var $user_id = false;
    var $user_username = false;
    var $cookie_identifier = false;
    var $user_logged_in = false;

    function __construct()
    {
        global $mysql_server;
        global $mysql_user;
        global $mysql_password;
        global $mysql_database_name;

        $this->db = new database($mysql_server, $mysql_user, $mysql_password, $mysql_database_name, true);

        $this->checkUserAuthentication();
    }


    public function Login($input_username, $input_user_password)
    {
        // If empty parameters return false
        if (empty($input_username) || empty($input_user_password))
        {
            return false;
        }

        $user_login = $this->db->q("SELECT user_id, username FROM `forum_user` WHERE username = ? AND password = ? LIMIT 1", 'ss' , $input_username, $input_user_password);
        if ($user_login != false)
        {
            $this->user_ip = $_SERVER['REMOTE_ADDR'];
            $this->user_id = $user_login[0]['user_id'];
            $this->user_username = $user_login[0]['username'];

            if($this->initiateSessionCookie() == true)
            {
                $this->user_logged_in = true;
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    private function initiateSessionCookie()
    {
        // Delete old sessions from this user or USE REPLACE instead
        $this->db->q("DELETE FROM `forum_session` WHERE userid = ?", 'i' , $this->user_id);

        $identifier = md5($this->cookie_salt . md5($this->user_username . $this->user_ip) . $this->cookie_salt);
        $token = md5($this->generateToken());
        $timeout = time() + 60 * 60 * 24 * 7;  // 7 days
        $timeout_minutes = 10080; // 7 days
        $init_session = $this->db->q("INSERT INTO forum_session SET session = ? 
                                                                  , token = ? 
                                                                  , userid = ? 
                                                                  , sess_start = now() 
                                                                  , last_activity = now() 
                                                                  , sess_expire = DATE_ADD(curdate(),INTERVAL ? MINUTE) 
                                                                  , ip = ?", 'ssiis' , $identifier, $token, $this->user_id, $timeout_minutes, $this->user_ip);
        if($init_session != false) {
            setcookie('auth', "$identifier:$token", $timeout);
            return true;
        }
        else {
            return false;
        }
    }

    private function generateToken()
    {
        $chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz!#&";

        for($i = 1; $i <= 20; $i++)
        {
            $rand_number = rand(0, 59);
            $random_string .= $chars[$rand_number];
        }
        return $random_string;
    }

    private function checkUserAuthentication()
    {
        $this->user_logged_in = false;

        list($_cookie_identifier, $_cookie_token) = explode(':', $_COOKIE['auth']);

        if(ctype_alnum($_cookie_identifier) && ctype_alnum($_cookie_token))
        {
            $_cookie_data['identifier'] = $_cookie_identifier;
            $_cookie_data['token'] = $_cookie_token;
        }
        else
        {
            return false;
        }

        $auth_user = $this->db->q("SELECT * 
                                   FROM forum_session a 
                                   LEFT JOIN 
                                        forum_user b ON a.userid = b.user_id 
                                   WHERE 
                                        a.session = ? AND 
                                        a.token = ? 
                                   LIMIT 1", 'ss' , $_cookie_data['identifier'], $_cookie_data['token']);
        if($auth_user != false)
        {
            if(time() > strtotime($auth_user[0]['sess_expire']))
            {
                return false;
            }

            if($_cookie_data['identifier'] == md5($this->cookie_salt . md5($auth_user[0]['username'] . $_SERVER['REMOTE_ADDR']) . $this->cookie_salt))
            {
                $this->user_logged_in = true;

                $this->user_id = $auth_user[0]['user_id']; 
                $this->user_username = $auth_user[0]['username']; 
                $this->user_ip = $_SERVER['REMOTE_ADDR'];

                return true;

                // TODO list
                // Renew token every 5 min? 
                // Renew cookie expire date
                // Renew session expire date
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    public function isUserLoggedIn()
    {
        return $this->user_logged_in;
    }

}

我在论坛所有页面中包含的会话处理程序。

 require_once('classes/user2.class.php');
 $user = new User2();
 session_start();

【问题讨论】:

    标签: php session authentication cookies


    【解决方案1】:

    为什么不从控制器中的 session_start() 开始(?)。

    如果不是一直需要,我会在控制器中使用一种方法来避免双重 session_start:

    class controller {
      $sStarted = false;  
    
      function sStart() {
        if (!$this->sStarted) {
          session_start();
          $this->sStarted = true;
        }
    

    问候 /t

    【讨论】:

    • 感谢您的意见!会调查一下 :) 课堂上还有什么看起来很愚蠢的吗?
    • 嗨,约翰,有点晚了,但无论如何:1. 替换全局变量。它们对您不利,请参考您的控制器来启动您的课程。 2. 如果 php 文件位于 www-root-scope 中,则不要将哈希值放入 php 文件中。当您的 php-handler 出现故障(发生这种事)时,您的盐就会暴露出来。
    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2015-06-19
    • 2013-09-08
    • 2021-10-19
    • 2021-09-04
    • 2015-03-25
    相关资源
    最近更新 更多