PHP会话类和使用/安全登录页面访问

时间:2014-01-05 05:29:57

标签: php security session login

这可能看起来像一个菜鸟问题,但我一直在搜索会议安全性,避免通常在网站中发现的所有安全漏洞,并启动以我希望的方式工作的会话(典型的如x)注销或从其他位置登录等的时间)。

我所追求的只是让我的会议开始工作,让他们安全地工作。不用多说,我有一个我为会议提供的课程

/* This SessionManager starts starts the php session (regardless of which handler is set) and secures it by locking down the cookie, restricting the session to a specific host and browser, and regenerating the ID.
*/

class SessionManager
{
/**
 * AOL users may switch IP addresses from one proxy to another.
 *
 * @link http://webmaster.info.aol.com/proxyinfo.html
 * @var array
 */
protected $aolProxies = array('195.93.', '205.188', '198.81.', '207.200', '202.67.', '64.12.9');

/**
 * This function starts, validates and secures a session.
 *
 * @param string $name The name of the session.
 * @param int $limit Expiration date of the session cookie, 0 for session only
 * @param string $path Used to restrict where the browser sends the cookie
 * @param string $domain Used to allow subdomains access to the cookie
 * @param bool $secure If true the browser only sends the cookie over https
 */
static function sessionStart($name, $limit = 0, $path = '/', $domain = null, $secure = null)
{
    // Set the cookie name
    session_name($name . '_Session');

    // Set SSL level
    $https = isset($secure) ? $secure : isset($_SERVER['HTTPS']);

    // Set session cookie options
    session_set_cookie_params($limit, $path, $domain, $https, true);
    session_start();

    // Make sure the session hasn't expired, and destroy it if it has
    if(self::validateSession())
    {
        // Check to see if the session is new or a hijacking attempt
        if(!self::preventHijacking())
        {
            // Reset session data and regenerate id
            $_SESSION = array();
            $_SESSION['IPaddress'] = isset($_SERVER['HTTP_X_FORWARDED_FOR'])
                        ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
            $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
            self::regenerateSession();

        // Give a 5% chance of the session id changing on any request
        }elseif(rand(1, 100) <= 5){
            self::regenerateSession();
        }
    }else{
        $_SESSION = array();
        session_destroy();
        session_start();
    }
}

/**
 * This function regenerates a new ID and invalidates the old session. This should be called whenever permission
 * levels for a user change.
 *
 */
static function regenerateSession()
{
    // If this session is obsolete it means there already is a new id
    if(isset($_SESSION['OBSOLETE']))
        return;

    // Set current session to expire in 10 seconds
    $_SESSION['OBSOLETE'] = true;
    $_SESSION['EXPIRES'] = time() + 10;

    // Create new session without destroying the old one
    session_regenerate_id(false);

    // Grab current session ID and close both sessions to allow other scripts to use them
    $newSession = session_id();
    session_write_close();

    // Set session ID to the new one, and start it back up again
    session_id($newSession);
    session_start();

    // Now we unset the obsolete and expiration values for the session we want to keep
    unset($_SESSION['OBSOLETE']);
    unset($_SESSION['EXPIRES']);
}

/**
 * This function is used to see if a session has expired or not.
 *
 * @return bool
 */
static protected function validateSession()
{
    if( isset($_SESSION['OBSOLETE']) && !isset($_SESSION['EXPIRES']) )
        return false;

    if(isset($_SESSION['EXPIRES']) && $_SESSION['EXPIRES'] < time())
        return false;

    return true;
}

/**
 * This function checks to make sure a session exists and is coming from the proper host. On new visits and hacking
 * attempts this function will return false.
 *
 * @return bool
 */
static protected function preventHijacking()
{
    if(!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent']))
        return false;


    if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT']
        && !( strpos($_SESSION['userAgent'], ÔTridentÕ) !== false
            && strpos($_SERVER['HTTP_USER_AGENT'], ÔTridentÕ) !== false))
    {
        return false;
    }

    $sessionIpSegment = substr($_SESSION['IPaddress'], 0, 7);

    $remoteIpHeader = isset($_SERVER['HTTP_X_FORWARDED_FOR'])
        ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];

    $remoteIpSegment = substr($remoteIpHeader, 0, 7);

    if($_SESSION['IPaddress'] != $remoteIpHeader
        && !(in_array($sessionIpSegment, $this->aolProxies) && in_array($remoteIpSegment, $this->aolProxies)))
    {
        return false;
    }

    if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT'])
        return false;

    return true;
}
}

所以这是我的班级,有几个功能。这是直截了当的。以下是我如何实现它。 (顺便说一下,这个班级的学分归于Tree Treehouse和其他一些人,所以我没有写下来。)

下面,我有一个登录页面,如果凭据正确,我应该开始会话:

// Earlier in the php I call it
include '/../session/session.php';

// 1. Check if the email exists (1 it does, 0 it doesn't)
    if ($emailFree == '1') {

            // Fetching login data
            $user->get_user($email);
            $pwStored = $user->password;
            $exStored = $user->exist;

            // 2. Check if they're activated
            if($exStored == '1') {

                // Encrypted input password
                $salt = generateSalt($email);
                $pwInput = generateHash($salt, $passw);

                // 3. Check if passwords match
                if($pwInput == $pwStored) {

                        SessionManager::sessionStart('awesomeWebsite');

                        header("Location: ../index.php");

                }

            }

            else {

                header("Location: ../index.php");

            }

    } 

    else {

如果凭据正确,那么它会重定向到索引页面,其中我有一个if语句来检查会话是否存在,如果是,那么用户可以访问“安全”页面。

include 'session/session.php';

session_start();
$sessionName = session_name();

if(isset($_SESSION['stalker']) && !empty($_SESSION['awesomeWebsite'])) {
    echo 'Junk, session initiated';
    echo $sessionName;
}
else if (!isset($_SESSION['stalker']) && empty($_SESSION['awesomeWebsite'])) {
    echo "NO session";
    echo $sessionName;
}
else {
    include 'login.php';
}

所以我遇到的问题是,在输入正确的凭据后,索引页面上的函数找不到会话。我看到有些人添加会话变量然后检查它们,我应该在创建会话时在我的类文件中添加会话变量,然后检查索引页中是否存在该会话变量?

我知道这很长并且不是最明显的,但感谢所有人提供的帮助和建议!

1 个答案:

答案 0 :(得分:0)

所以我现在有会议工作,这是代码:

Login.php(逻辑)

if({
SessionManager::sessionStart('website');                
$_SESSION['logged_in'] = 'true';
header("Location: ../index.php");

的index.php

SessionManager::sessionStart('website');

$logged_in = $_SESSION['logged_in'];

if(isset($logged_in) && !empty($logged_in)) {
    echo 'Junk, session initiated';
    echo "<br>" . $logged_in;
}
else if (isset($logged_in) && empty($logged_in)) {
    echo "NO session";
    echo "<br>" . $logged_in;
}
else {...}

现在似乎工作,我想我只需要声明一个会话变量然后添加“SessionManager :: sessionStart('website');”到索引页面的顶部,为会话逻辑调用我的类。