1. 程式人生 > >session和cookie的知識總結

session和cookie的知識總結

ssi -a 問題 機制 隨著 自己的 unix 關閉 相關

1、HTTP協議

由HTTP客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP連接。HTTP服務器則在那個端口監聽客戶端發送過來的請求。一旦收到請求,服務器(向客戶端)發回一個狀態行,比如"HTTP/1.1 200 OK",和(響應的)消息,消息的消息體可能是請求的文件、錯誤消息、或者其它一些信息。(引自百度百科)總之,客戶端通過http協議request發送請求到服務器端,服務器端做出響應response。http協議最大的特點是無連接、無狀態。無連接指每次請求響應完連接關閉。設計者的初衷是在互聯網大量的訪問下避免資源的浪費,隨著頁面資源的豐富多彩,頁面包含圖片、視頻、文字等信息,每次請求都建立一個連接性能很低效,在後來的HTTP/1.0中以及HTTP/1.1中,引入了重用連接的機制,就是在http請求頭中加入Connection: keep-alive

來告訴對方這個請求響應完成後不要關閉,下一次咱們還用這個請求繼續交流。協議規定HTTP/1.0如果想要保持長連接,需要在請求頭中加上Connection: keep-alive,而HTTP/1.1默認是支持長連接的,有沒有這個請求頭都行。HTTP無狀態,是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

2、cookie和session的本質

cookie和session都是針對http協議無狀態而提出的一種保存客戶端和服務器端保持連接狀態的機制。

3、cookie簡介

cookie最早是網景公司在93年發明的這樣的技術。主要是用來達成客戶端和服務器端持續連接的狀態,來解決無狀態的問題,讓服務器知道用戶是誰。cookie總是保存在客戶端中

,根據存儲位置可以劃分為兩類,一種是內存cookie,一種是硬盤cookie。內存cookie是由瀏覽器保存在內存中,瀏覽器關閉後就消失了,存在時間短暫。硬盤cookie是存儲在硬盤中的,可以設置過期時間,除非用戶清理cookie或者時間過期,存儲在硬盤中的cookie不會消失,存在時間長期。永久登陸、網站換膚、購物車等可以用cookie實現。

3.1 cookie操作(以php為例)

設置cookie

bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain

= "" [, bool $secure = false [, bool $httponly = false ]]]]]] )

setcookie() 定義了 Cookie,會和剩下的 HTTP 頭一起發送給客戶端。 和其他 HTTP 頭一樣,必須在腳本產生任意輸出之前發送 Cookie(由於協議的限制)。 請在產生任何輸出之前(包括 <html><head> 或者空格)調用本函數。

一旦設置 Cookie 後,下次打開頁面時可以使用 $_COOKIE 讀取。 Cookie 值同樣也存在於 $_REQUEST

name

Cookie 名稱。

value

Cookie 值。 這個值儲存於用戶的電腦裏,請勿儲存敏感信息。 比如 name‘cookiename‘, 可通過 $_COOKIE[‘cookiename‘] 獲取它的值。

expire

Cookie 的過期時間。 這是個 Unix 時間戳,即 Unix 紀元以來(格林威治時間 1970 年 1 月 1 日 00:00:00)的秒數。 也就是說,基本可以用 time() 函數的結果加上希望過期的秒數。 或者也可以用 mktime()。 time()+60*60*24*30 就是設置 Cookie 30 天後過期。 如果設置成零,或者忽略參數, Cookie 會在會話結束時過期(也就是關掉瀏覽器時)。

Note:

你可能註意到了,expire 使用 Unix 時間戳而非 Wdy, DD-Mon-YYYY HH:MM:SS GMT 這樣的日期格式,是因為 PHP 內部作了轉換。

path

Cookie 有效的服務器路徑。 設置成 ‘/‘ 時,Cookie 對整個域名 domain 有效。 如果設置成 ‘/foo/‘, Cookie 僅僅對 domain/foo/ 目錄及其子目錄有效(比如 /foo/bar/)。 默認值是設置 Cookie 時的當前目錄。

domain

Cookie 的有效域名/子域名。 設置成子域名(例如 ‘www.example.com‘),會使 Cookie 對這個子域名和它的三級域名有效(例如 w2.www.example.com)。 要讓 Cookie 對整個域名有效(包括它的全部子域名),只要設置成域名就可以了(這個例子裏是 ‘example.com‘)。

舊版瀏覽器仍然在使用廢棄的 ? RFC 2109, 需要一個前置的點 . 來匹配所有子域名。

secure

設置這個 Cookie 是否僅僅通過安全的 HTTPS 連接傳給客戶端。 設置成 TRUE 時,只有安全連接存在時才會設置 Cookie。 如果是在服務器端處理這個需求,程序員需要僅僅在安全連接上發送此類 Cookie (通過 $_SERVER["HTTPS"] 判斷)。

httponly

設置成 TRUE,Cookie 僅可通過 HTTP 協議訪問。 這意思就是 Cookie 無法通過類似 JavaScript 這樣的腳本語言訪問。 要有效減少 XSS 攻擊時的身份竊取行為,可建議用此設置(雖然不是所有瀏覽器都支持),不過這個說法經常有爭議。 PHP 5.2.0 中添加。 TRUEFALSE

更新cookie

更新cookie和設置cookie用同一個函數即可。需要註意的是cookie的相關參數必須與設置時相同否則更新失敗。

查看cookie

cookie數據都會保存在$_COOKIE的超全局數組中

刪除cookie

刪除cookie同樣是使用setcookie()函數,只需將值設為空,過期時間設為當前時間之前的時間比如(time()-1)就可以刪除cookie,與更新cookie相同,刪除cookie時後面的參數也必須與設置時一致否則是刪除不了的。

cookie的常用操作我封裝在一個類中方便使用。可以點擊查看

4、session簡介

Session 是 用於保持狀態的基於 Web服務器的方法。Session 允許通過將對象存儲在 Web服務器的內存中在整個用戶會話過程中保持任何對象。

session的工作原理:

技術分享圖片

4.1、準備建立會話的時候,php會查看請求中是否包含session_id。如果沒有服務器會在自己的內存裏創建一個新的變量,這個變量就是session_id.

4.2、服務器會把這個session_id發送到瀏覽器保存,一般瀏覽器會把這個id保存在cookie中。

4.3、之後每次瀏覽器訪問服務器的時候,都會攜帶cookie中存儲的這個session_id值,這樣服務器就認識這個瀏覽器了。

4.4、服務端這個session_id的變量就可以存放任意的會話數據,這樣數據是經過序列化之後存放進去的。

4.5、每次瀏覽器訪問服務器,都可以憑借的session_id到服務器的這個變量中認領自己的信息

4.6、如果想銷毀會話,可以刪除會話中的數據,銷毀會話文件,默認是存儲在文件中的。也可以自定義存儲在數據庫中或者緩存中。

php中如何使用session

1、開啟會話:session_start();

2、可以通過$_SESSION來設置相關值,設置和讀取都是用這個全局變量。

3、銷毀session session_destory();

技術分享圖片

這是沒設置之前的截圖

<?php 

//開啟會話
session_start();

header(‘content-type:text/html;charset=utf-8‘);
$_SESSION[‘username‘]=‘張三‘;
$_SESSION[‘age‘]=18;
echo ‘session的名字:‘.session_name().‘<br>‘;
echo ‘session的ID:‘.session_id();

setcookie(session_name(),session_id(),time()+60*60);

運行這個文件之後,

技術分享圖片

由於在代碼中自己設置了一個cookie設置了過期時間,所以這裏有兩個cookie

第一次訪問後的截圖可以看到請求頭中是不包含session_id的信息的。

技術分享圖片

再來看第二次訪問的結果:

<?php 
session_start();
header(‘content-type:text/html;charset=utf-8‘);
var_dump($_SESSION);

技術分享圖片

服務器會根據sessionid的信息查看文件獲取數據。

技術分享圖片

技術分享圖片

可以看到文件存儲的序列化後的信息。

銷毀會話:

<?php
//銷毀session步驟
//1、將$_SESSION清除  $_SESSION=[];
//2、將cookie中的sessionid刪除 setcookie();
//3、銷毀會話  session_destory

session_start();
//將$_SESSION 數據清空
 $_SESSION=[];
 //刪除會話cookie
if(ini_get(‘session.use_cookies‘)){
	$params=session_get_cookie_params();//獲取會話 cookie 參數
	var_dump($params);
	 setcookie(session_name(),session_id(),time()-1,$params[‘path‘],$params[‘domain‘],$params[‘secure‘],$params[‘httponly‘]);
	 setcookie(session_name(),session_id(),time()-1);
}

//銷毀會話
session_destroy();

第一個刪除cookie信息是刪除默認的cookie信息,第二個是刪除自己設置的cookie信息 只刪除一個是沒用的

技術分享圖片

至此,session從建立到刪除的過程結束。

下面簡述下當用戶禁用瀏覽器的cookie時設置session的方法。

原理:只要吧sessionid傳遞給服務器就可以,因此可以通過url傳遞值,當然這樣沒有cookie安全。這裏以火狐瀏覽器為例

首先,禁用瀏覽器cookie

技術分享圖片

技術分享圖片

註意:如果你正在登陸博客的話 操作會讓你的登陸註銷的。悲催的我寫著這篇文章的時候,屏蔽後讓我先登錄,臥槽,幸虧沒有在原頁面跳轉,不然我一上午的辛苦就白費了,與君共勉。

廢話少說,題接上文。

禁用cookie後

<?php 
// 當用戶禁用cookie下session的使用
session_start();
header(‘content-type:text/html;charset=utf-8‘);
$_SESSION[‘a‘]=‘a‘;
echo "<a href=‘dump-session.php?".session_name()."=".session_id()."‘ >查看session</a>";

技術分享圖片

技術分享圖片

可以看到禁用cookie後第一次訪問跟之前的結果是相同的 ,當打印結果也就是第二次訪問時

技術分享圖片

這是url攜帶phpsessionid時的情況,

session和cookie的知識總結