[Codeingter]config.php的cookie_secure

前言

前陣子的在開發的時候,有一項是要在登入頁做remeber me的功能

這其實還滿簡單的,畢竟只要有買過php的書幾乎都會有範例

不同的是之前是純粹用PHP寫,現在用的是CI

以前沒有用過CI提供的cookie存取功能,但有看過config檔裡面有相關的設定


/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path' = Typically will be a forward slash
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix'] = "c_";
$config['cookie_domain'] = $_SERVER['HTTP_HOST'];
$config['cookie_path'] = "/";
$config['cookie_secure'] = TRUE;

所以就先設定了一下,但我當下沒有發現自己犯了一個錯…(官方的說明文件也沒有寫得很清楚,還是看code最準XD)

把remeber me功能的做完的時候,當下測試的時候發現登入功能GG了(…WTF)

一開始是馬上去看我剛剛寫的程式是不是有BUG,但還真的沒有啊…

神奇的是我把剛剛寫的code刪光光,登入功能依然GG…

所以我就開始想想我寫code之前做了什麼事?

config~我改了config,但我只是設定cookie相關的config而已

也沒有更動到session的東西啊….

秉持著爬source code的精神,終於讓我釐清事情的來龍去脈…容我慢慢道來

文件vs註解

我在改config相關的cookie設定前有先去看官方的說明文件

其中有一項是設定$config[‘cookie_secure’]

文件是這樣寫的:

The secure boolean is only needed if you want to make it a secure cookie by setting it to TRUE.

所以我就把cookie_secure設為TRUE <—(這就是我犯的錯誤)

但後來在檢查config.php的時候我發現它的註解的解釋是:

/*
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
*/

所以,如果將CI config.php的cookie_secure的參數設為TRUE

代表利用$this->input->set_cookie()設定的cookie只能透過https的方式傳輸!

但我做的那個網站並沒有用https…這就是最根本的問題 (如果官方的文件和助解一樣的話我應該就不會把cookie_secure設成TRUE了)

還有還有

debug到這邊應該就可以告一個段落了~~

但是!!我還是沒搞懂為何cookie_secure設為TRUE之後,我TMD的就不能登入

基於爬爬source code的精神,發現..在/system/libraries/Session.php有一段程式碼解決了我最後一個疑惑:


 // Fetch the cookie
 $session = $this->CI->input->cookie($this->sess_cookie_name);

 // No cookie? Goodbye cruel world!...
 if ($session === FALSE)
 {
   log_message('debug', 'A session cookie was not found.');
   return FALSE;
 }

 // Decrypt the cookie data
 if ($this->sess_encrypt_cookie == TRUE)
 {
   $session = $this->CI->encrypt->decode($session);
 }
 else
 {
   // encryption was not used, so we need to check the md5 hash
   $hash = substr($session, strlen($session)-32); // get last 32 chars
   $session = substr($session, 0, strlen($session)-32);

   // Does the md5 hash match? This is to prevent manipulation of session data in userspace
   if ($hash !== md5($session.$this->encryption_key))
   {
     log_message('error', 'The session cookie data did not    match what was expected. This could be a possible hacking attempt.');
     $this->sess_destroy();
     return FALSE;
   }
 }

CI在讀取seesion的時候會有一個檢查機制

1.先檢查Server上的session和client端cookie裡面加密後的session是否存在

2.檢查是否為加密的值

3.比對seesion和cookie是否match

總結因果

1.目前開發的網站不是走HTTPS

2.把config.php的cookie_secure的參數設為TRUE

3.帳密都輸入正確時,程式存一個seesion在Server上,CI則自動在cookie端存一個加密後的session值

4.轉跳到登入後的頁面時,會檢查是否有登入,但這個機制觸發了..

5.CI在讀取seesion時會去比對seesion和cookie是否match

6.但無法取得這個cookie的值…所以return FALSE…死在

log_message('debug', 'A session cookie was not found.');

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s