php中的session_id詳解


php中session_id()函數原型及說明session_id()函數說明:stringsession_id([string$id])session_id() 可以用來獲取/設置 當前會話 ID。為了能夠將會話 ID 很方便的附加到 URL 之后, 你可以使用常量 SID 獲取以字符串格...

php中session_id()函數原型及說明

 

session_id() 可以用來獲取/設置 當前會話 ID。

為了能夠將會話 ID 很方便的附加到 URL 之后, 你可以使用常量 SID 獲取以字符串格式表達的會話名稱和 ID。 請參考 會話處理。

session_id()函數參數:

id

如果指定了 id 參數的值, 則使用指定值作為會話 ID。 必須在調用 session_start() 函數之前調用 session_id() 函數。 不同的會話管理器對於會話 ID 中可以使用的字符有不同的限制。 例如文件會話管理器僅允許會話 ID 中使用以下字符:a-z A-Z 0-9 , (逗號)和 - (減號)

Note: 如果使用 cookie 方式傳送會話 ID,並且指定了 id 參數, 在調用 session_start() 之后都會向客戶端發送新的cookie, 無論當前的會話 ID 和新指定的會話 ID 是否相同。

session_id()函數返回值:

session_id() 返回當前會話ID。 如果當前沒有會話,則返回空字符串("")。

 

php會話ID如何生成以及會話ID長度

   

  一個訪問者訪問你的 web 網站將被分配一個唯一的 id, 就是所謂的會話 id. 這個 id 可以存儲在用戶端的一個 cookie 中,也可以通過 URL 進行傳遞. Session會話用來追蹤每個用戶的會話,使用服務器生成的SessionID進行標識,用以區分用戶。Session存放在服務器的內存中,SessionID存放在服務器內存和客戶機的Cookie里面。這樣,當用戶發出請求時,服務器將用戶Cookie里面記錄的SessionID和服務器內存中的SessionID進行比對,從而找到這個用戶對應的Session進行操作。所以,如果客戶機禁止Cookie的話,Session也不能使用。

php會話ID是如何產生的?PHP默認的session id生成算法介紹

    以php5.3.6的源碼為例,進入/ext/session目錄,生成session id的函數位於session.c文件的345行,c語言函數原型如下:

 

PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);

  有興趣的可以具體分析實現原理。

 

PHP默認的session id長度

截取一些實際的php 5.4.6服務端生成的session id如下:

sess_00nrqa20hjrlaiac0eu726i4q5      sess_89j9ifuqrbplk0rti2va2k1ha0      sess_g2rv1kd6ijsj6g6c9jq5mqglv5  
sess_04es72a83tqsl0jqd3cvrc4s01      sess_8b7a5lme60g49lvk4u4jiemdn1    sess_g3uk6d3gbashg5eoq0b2k7vsk0  
sess_04u0ns0oobh2g93t009bij2rq0    sess_8dfvkiv8ml44fdqrk1rcmjchs4       sess_g64tddhbo8pbj8bs7bel44rf35  
sess_0592dolr5m0k392fah6c9preg7    sess_8fhgkjuakhatbeg2fa14lo84q1      sess_g6kl828qqsnvdrse7ff52cl2a4  
sess_066g8irr0m22iqotscepub4e13     sess_8gn03i9j1tta7655qfj6nl1l53       sess_g8t45j6qce7mf55nk14cotj5i4  
sess_08nr1fav9jqs2pdi5qlpsmd247     sess_8gvu05313o7p9usksaacaiegu6    sess_gbtjmr57iat86c8ve86ar5nh30

可見具體的session id 為 “sess_”后面的部分,長度為26位,此長度僅限於php 5.4.6.

php session_id()用法代碼舉例如下:

輸出session_id()詳細代碼:

<?php

  session_start();//開啟session會話

  echo session_id();//輸入session_id

  // 輸出 08nr1fav9jqs2pdi5qlpsmd247
?>

 

設置 session_id()詳細代碼:

<?php

  session_id("www.169it.com");//設置session_id 

  session_start();//開啟session會話

  echo session_id();

  // 輸出 www.169it.com
?>

 總結:

 

php中的session_id函數恢復session的內容方法

  php的session是可以程序恢復的,這個和java不太一樣。session的恢復機制可以實現多個應用程序session的共享,因為php的session都是以文件形式或者數據庫存儲的。首先是session_id的獲取是通過session_id()函數獲取,這個值可以進行傳遞。程序恢復session,首先要知道session_id,大家通過手冊可以知道session的恢復通過session_id($id);但是在恢復時要注意一個先后順序,要得到之前session的內容,必須在session_start()之前執行session_id($id),這樣才能在執行了session_start時初始化session的時候恢復到之前的內容,否則的話你得到的是一個空的session,你什么也得不到。之前session被重新初始化了。這個和session_start()的作用有密切關系,因為session_start告訴php,session要初始化,要從session文件中反序列化session內容,所以session_start的作用就是把之前存儲的文件內容反序列化。session_start序列化之前要知道session_id,如果沒有就生成一個新的session_id。如果有就反序列化相應文件的內容。

 

后續:

Session 的工作機制是:為每個訪問者創建一個唯一的 id (UID),並基於這個 UID 來存儲變量。UID 存儲在 cookie 中,亦或通過 URL 進行傳導。

 

前序:


首先要明白PHPSESSID看似多次刷新都不會改變其實是沒有刪除本地相關聯的cookie,刪除的方法

session_destroy();//刪除服務器端的session文件

setcookie(session_name(),'',time()-3600,'/');//刪除本地相關聯的cookie

session_unset();//清空內存中的cookie或者是$_SESSION = array(); 

然后再刷新相應的頁面你就會看到PHPSESSID會發生變化了,根據此可以得:如果session文件已經創建則不重新生成PHPSESSID,否則需要重新生成,生成規則,就看下邊嘍……!



--------------------------------------------------------------------------------------------------------------------------------------

現在經過測試應該是不是檢測session文件是否存在,而是檢測PHPSESSID的cookie是否存在並且是否未過期!特此更正!

------------------------------------------------------------------------------------------------

可能PHP開發者心中多少都思考過這么兩個問題:

種植在客戶端瀏覽器中的PHPSESSIONID會出現重復嗎?
PHPSESSIONID安全性如何,有沒可能被黑客輕易的仿造呢?
帶上這個問題,我稍微注意了一下PHP的源碼后,疑問也就有了答案。

PHP在使用默認的 session.save_handler = files 方式時,PHPSESSIONID的生產算法原理如下:


hash_func = md5 / sha1 #可由php.ini配置
PHPSESSIONID = hash_func(客戶端IP + 當前時間(秒)+ 當前時間(微妙)+ PHP自帶的隨機數生產器)

從以上hash_func(*)中的數據采樣值的內容分析,多個用戶在同一台服務器時所生產的PHPSESSIONID重復的概率極低(至少為百萬份之一),設想,但台動態Web Server能到2000/rps已經很強悍了。

另外,黑客如果要猜出某一用戶的PHPSESSIONID,則他也必須知道“客戶端IP、當前時間(秒、微妙)、隨機數”等數據方可模擬。

以下是截取PHP源碼中PHPSESSIONID實現片段:

gettimeofday(&tv, NULL);

if (
zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
Z_TYPE_PP(array) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS)
{
remote_addr = Z_STRVAL_PP(token);
}


spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);

switch (PS(hash_func))
{
case PS_HASH_FUNC_MD5:

PHP_MD5Init(&md5_context);

PHP_MD5Update(&md5_context, (unsigned char *) buf, 

strlen(buf));

digest_len = 16;

break;

case PS_HASH_FUNC_SHA1:

PHP_SHA1Init(&sha1_context);

PHP_SHA1Update(&sha1_context, (unsigned char *) buf, 

strlen(buf));

digest_len = 20;

break;

default:

php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");

efree(buf);

return NULL;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM