2014-01-05 96 views
0

这可能看起来像一个noob问题,但我一直在寻找天和学习会话安全性,避免通常在网站中发现的所有安全漏洞,并启动会话,工作我希望他们的方式(典型的例如x时间注销或从其他位置登录等)。PHP会话类别和使用/安全登录页面访问

我之后所有的工作都是让我的课程开始工作,让他们安全地工作。毋庸置疑,我有一门课,我包括本届会议

/* 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; 
} 
} 

所以这是我的班级与几个功能。这很简单。以下是我如何实施它。 (顺便说一句,这个类的功劳归功于Team 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'; 
} 

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

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

+0

只是为了排除这是一个浏览器问题,请尝试删除您所使用域和所有子域的所有cookie并重试,并确保浏览器启用会话cookie。 – Mike

+0

是的。会话是一个会话,但可能不是存储任何登录信息的** SAME **会话。设置您在任何地方检查的密钥/值是确认您不会“丢失”登录会话并获取其他新/不相关会话的好方法。例如'if(isset($ _ SESSION ['loggedin'])&& $ _SESSION ['logged_in'])){...用户正确登录...} –

+0

好吧,我在开始会话后创建了一个会话变量: \t \t \t $ _SESSION ['logged_in'] ='true'; 然后在索引 ' $ logged_in = $ _SESSION ['logged_in']; (isset($ logged_in)&&!empty($ logged_in)) ' if但是它仍然没有启动一个会话出于某种原因。 – Kenny

回答

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');”到索引页面的顶部以调用我的类来获取会话逻辑。