Session & Cookies
因為HTTP通訊協定的Stateless 特性,所以需要把資料儲存在某個地方記住狀態。 Cookie是一種將狀態記錄於用戶端的技術
Cookie的運作原理 當程式請用戶端儲存Cookie時,只要瀏覽器支援Cookie,而且使用者未關閉此功能,瀏覽器就會依照程式的要求, 將變數與變數值儲存 於用戶端電腦內(格式為純文字檔)。使用者對伺服器的後續連線便會持續地帶有Cookie,讓程式可以取回先前保存的值:
因為Cookie儲存在用戶端電腦上,只要使用 者不將之刪除,資料即可保留一段時間,不會因為關閉瀏覽器而消失,而且同一網站的各網頁之間也可以共享資料。使用Cookie最常見的例子便是購物網站,許多購物網站製作購物車時會使用Cookie, 當使用者將產品放入購物車之後, 程式就會將資料寫入Cookie。
如此就算關閉瀏覽器或是電腦,未來使用者只要以同一電腦環境連上購物網站,程式便可由Cookie取回前次選取的商品,將購物車恢復為 上次的狀態。
使用Cookie時有以下的限制: 大多數瀏覽器會限制Cookie最大不得超過4096Bytes:所以Cookie只適合用來存放少量資料,如使用者名稱、帳號、上次到訪時間...等。
因為 Cookie是以純文字的方式儲存與傳送,所以可能會被檢視、攔截或是竄改,故重要或機密資料(例如使用者密碼)請勿存放於 Cookie。
此外,由於Cookie資訊會放在HTTP通訊表頭中,而HTTP的通訊表頭必須在所有輸出之前送出。所以setcookie()函式執行之前, 若有echo()或HTML標籤等輸出,將會導致setcookie()函式執行錯誤。
Session的意義 一個Session代表使用者開啟瀏覽器連線網站,一直到關閉瀏覽器為止的工作期間。 此期間不論使用者瀏覽該網站的任何網頁, 甚 至離開網站後又回來,對於該網站而言都是同一個Session。不過只要重新開啟瀏覽器便是一個新的Session,所以即使是同一使用者,開啟兩個瀏覽器視窗連線同一網站,將被視為兩個獨立的Session。
當網頁程式使用 Session 技術儲存狀態或資料時,不論是否為相同頁面,只要在同一個 Session 內即可存取同一份資料。 但若是不同 Session, 就算在同一部電腦、使用相同瀏覽器、連線相同網頁、讀寫同一名稱的資料, 其所存取的仍是兩份獨立不同狀態的 資料。
Session 是一種將資料記錄於伺服器的技術, 下面是其運作的示意圖:
由上面示意圖可以看到程式必須以 Session ID 來存取狀態與資料。
一般情況下, Session ID會存放在沒有到期日的Cookie 內 (但是其他 Session 資料皆儲存 於伺服器上)。 所以同一個網站的相同與不同網頁之間可以藉 由 Cookie 掌握同一個 Session ID, 進而存取 同一份資料。 不過因為 Cookie 沒有到期日, 代表其在關閉瀏覽器時會自動刪除,因此關閉瀏覽器後重新 連線同一網站, 得到的便是新的 Session ID。
此外, 因為 Session 是隨著瀏覽器的開啟與關 閉而生滅的機制, 而且將資料記錄在伺服器而 非用戶端。 所以相當適合使用在會員登入、購物結帳...等, 各網頁需要共享機密或重要資料, 且每次連線 都會因狀況不同而必須儲存不同資料的場合。
要在PHP程式中使用 Session, 只要先執行 session_start() 函式,開啟 Session 功能, 即可 在後續步驟存取 Session。不過如前面所提到的, Session 預設使用 Cookie 傳遞 Session ID。 而 Cookie 資訊會放在 HTTP 通訊表頭中,且HTTP的通訊表頭必須在所有輸出之前送出。
所以 session_start() 函式執行之前, 若有 echo()、或 HTML 標籤等輸出, 將會導致 session_start() 函式執行錯誤, 而無法使用 Session 功能。
在 Rails 裡,session 是怎麼建立的呢? 答案就是 cook- ie:當你登入一個網站時,網站的伺服器就即時產生一個 id 給你,當作 cookie 放在你的瀏覽 器裡。 這 id 其實只是一個長度 32 位數的英文字母字串。 每次你要新的資訊時,你的瀏覽器 會把那串字給伺服器,這樣伺服器就知道你是誰了。
第一次進網站,server給使用者一個session,所以新增資料進去database
INSERT INTO sessions
(session_id
, data
, created_at
, updated_at
) VALUES ('d85e5a94f6ff7a032f6e091b3bfe2b44', 'BAh7B0kiC2xvY2FsZQY6BkVGIgd6aEkiEF9jc3JmX3Rva2VuBjsARkkiMVBB\nMUxiSmhSVDBxUGxFZWhEWGp6K3lYY3QvT0tVQ0ZlelBVaEljdTdSNFE9BjsA\nRg==\n', '2016-03-29 06:48:31', '2016-03-29 06:48:31')
使用者第二次進,server就去database去找這筆session
SELECT sessions
.* FROM sessions
WHERE sessions
.session_id
= '5139fe1e98e99f126847ec2ac8cae50a' ORDER BY sessions
.id
ASC LIMIT 1
使用者訪問網站,server給使用者一個session,裡面有session id和譬如說log_out_day讓使用者可以登入七天 之後使用者再訪問,用log_out_day用來判斷使用者應該是登入還登出。 訪問網站也有給cookie,譬如使用這最後看的影片,下次使用者進頁面就知道要給哪個, 重要的東西放Session,不重要放在Cookie。
jimmy說的session_id只是一個欄位,kyle說的是真的瀏覽器的session 記得不同伺服器為了共用session所以要把session存在database嗎? 登入就給session塞在cookie裡,session藏機密資料例如access_token
看member_controller
if response["access_token"].present?
sign_in(response)
看session_helper
def sign_in 登入時候把access token存進去session session[:user] = { "access_token" => token, "refresh_token" => response["refresh_token"], "expires_in" => response["expires_in"], "created_at" => response["created_at"] }
def logout登出時候把session[:user] 清空 session[:user] = {}
- 用if session[:user] 看是不是有登、 」「’頗ㄏsession[:user]n m≤≥/
關鍵字: session、 cookie、 開發人員工具的 -> resources -> session storage、 session storage
使用者訪問會給session帶token,使用者到網站頁面的表單裡面會有hide欄位帶token, 傳表單出去server 使用者的session的token跟表單的token,一樣才ok。
駭客可以撈封包拿到連結讓使用者點,如果使用者點到假連結,送出去的請求不是在真的頁面的表單產生, 不會有token,這樣跟使用者session id的token就對不起來。