天天看點

discuz 登入cookie有效期設定解析

discuz在source\class\class_member.php腳本中函數on_login 内進行驗證登入資訊,以下是驗證代碼

$result = userlogin($_GET['username'], $_GET['password'], $_GET['questionid'], $_GET['answer'], $this->setting['autoidselect'] ? 'auto' : $_GET['loginfield'], $_G['clientip']);           

如果驗證正确( $result['status'] > 0 ),接下來

setloginstatus($result['member'], $_GET['cookietime'] ? 2592000 : 0);           

進行cookie資訊寫入,其中 $_GET['cookietime'] 在普通登入時,沒傳,是以,setloginstatus得第二各參數傳的是0,這個0标記一下,繼續看setloginstatus,

function setloginstatus($member, $cookietime) {              global $_G;              $_G['uid'] = intval($member['uid']);              $_G['username'] = $member['username'];              $_G['adminid'] = $member['adminid'];              $_G['groupid'] = $member['groupid'];              $_G['formhash'] = formhash();              $_G['session']['invisible'] = getuserprofile('invisible');              $_G['member'] = $member;              loadcache('usergroup_'.$_G['groupid']);              C::app()->session->isnew = true;              C::app()->session->updatesession();                  dsetcookie('auth', authcode("{$member['password']}\t{$member['uid']}", 'ENCODE'), $cookietime, 1, true);              dsetcookie('loginuser');              dsetcookie('activationauth');              dsetcookie('pmnum');                  include_once libfile('function/stat');              updatestat('login', 1);              if(defined('IN_MOBILE')) {              updatestat('mobilelogin', 1);              }              if($_G['setting']['connect']['allow'] && $_G['member']['conisbind']) {              updatestat('connectlogin', 1);              }              $rule = updatecreditbyaction('daylogin', $_G['uid']);              if(!$rule['updatecredit']) {              checkusergroup($_G['uid']);              }              }           

其中記錄使用者登入資訊的核心部分就是

dsetcookie('auth', authcode("{$member['password']}\t{$member['uid']}", 'ENCODE'), $cookietime, 1, true);           

$cookietime就是setloginstatus傳入的第二參數,繼續為0,接下來解析dsetcookie

function dsetcookie($var, $value = '', $life = 0, $prefix = 1, $httponly = false) {                  global $_G;                  $config = $_G['config']['cookie'];                  $_G['cookie'][$var] = $value;              $var = ($prefix ? $config['cookiepre'] : '').$var;              $_COOKIE[$var] = $value;                  if($value == '' || $life < 0) {              $value = '';              $life = -1;              }                  if(defined('IN_MOBILE')) {              $httponly = false;              }                      $life = $life > 0 ? getglobal('timestamp') + $life : ($life < 0 ? getglobal('timestamp') - 31536000 : 0);                  if(strstr($var,"_auth")){              discuz_error::write_error_log("<br>".var_export($_COOKIE[$var],true)."<br>");                  }                  $path = $httponly && PHP_VERSION < '5.2.0' ? $config['cookiepath'].'; HttpOnly' : $config['cookiepath'];              $secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;              if(PHP_VERSION < '5.2.0') {              setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure);              } else {              setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure, $httponly);              }              if(strstr($var,"_auth")){              discuz_error::write_error_log("<br>".$life.'_'.$var.'_'.var_export($_COOKIE[$var],true)."<br>");                  }              }           

兩個地方設定了cookie,第一就是上面标藍的

$_COOKIE[$var] = $value;           

直接将,auth傳入cookie,然後又在後面的标藍處,進行第二次cookie值的設定,

setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure, $httponly);           

$life,在傳入時,如果小于0,或者,$var為空時,$life被指派為-1,接下來 $life根據值-1,重新指派為 getglobal('timestamp') - 31536000,在執行setcookie時,就把$_COOKIE[$var]給清空,如果$life傳入時大于0,在執行setcookie前,$life被指派為getglobal('timestamp') + $life,之前函數傳入的$life,就是該 $_COOKIE[$var]的有效期。下面是重點,在登陸時,$life被傳入時為0,執行setcookie時,$life也就是cookie的過期值也是為0,在php官方手冊中的解釋是

bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )           

expire The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. In other words, you'll most likely set this with the time() function plus the number of seconds before you want it to expire. Or you might use mktime(). time()+60*60*24*30 will set the cookie to expire in 30 days.  If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes). 其中,标藍處的意思就是,當cookie的過期時間$expire為0,或是沒有設定時,cookie的儲存時間與浏覽器程序一緻,在浏覽器程序未關閉狀态,cookie均會存在,浏覽器關閉後cookie會消失,就是說在普通登入時,記錄使用者登入狀态的函數,設定的cookie有效期就是浏覽器打開該網站的有效期,關閉後,cookie值随之消失。

另外,使用者在登入時選擇,自動登入,如下圖

<input type="checkbox" class="pc" name="cookietime" id="cookietime_Lz363" tabindex="1" value="2592000" fwin="login">           

在執行 setloginstatus,傳入的$ cookietime的就是2592000,進而,将該該值傳入cookie,也就是dsetcookie的$life大于0,并且值為 2592000 ,使用者的登入狀态存在時間就是 2592000(60*60*24*30),30天。