上次介紹了HTTP的原理以及HTTPS的加密過程,本章将圍繞HTTP請求常見的字段cookie、session、token進行詳解!
HTTP引入cookie和session的原因
我們知道,HTTP是一種無狀态協定,一旦資料進行交易後,連接配接就會斷開,這樣将會導緻下一次進行資料交易時,會産生一個與之前無關聯的新的交易資料,就如我們網上購物,第一次将商品加入購物車A中,再次加入購物車時,就不知道是加入的購物車A還是B了。為了解決這個問題,在指定時間内能夠儲存一個完整的會話(理論上一個完整的會話指的是用戶端與伺服器的所有請求操作過程),分别從用戶端和伺服器兩個方向分别引入了cookie和session。用戶端利用cookie來儲存相應的會話資訊,伺服器通過用戶端傳遞的cookie來判斷用戶端的身份;伺服器利用session來儲存相應的會話資訊(用戶端的狀态),用戶端檢視自身資訊是否存在于伺服器中
cookie的實作機制
-
cookie存儲會話資訊的過程:
用戶端通過浏覽器發送Http請求(攜帶用戶端的個人資訊等)到伺服器,伺服器接收到請求後,傳回響應内容,并且頒發給用戶端攜帶用戶端個人資訊的set-cookie(一段小文本,通過響應頭傳回給用戶端,不同網站頒發的cookie不一樣),訓示用戶端建立一個cookie(儲存這段文本值),在此之後,cookie失效之前,用戶端每次給伺服器發送請求,都會在請求頭中攜帶該cookie值,伺服器每次通過分析cookie資訊,動态生成與用戶端相應的内容(伺服器可根據需求對cookie進行修改,網站之間不可修改cookie值)
注:用戶端若将cookie值存儲在記憶體中,當浏覽器被關閉後,cookie将會被清除,若存在硬碟中,浏覽器關閉,cookie不會被清除
- 伺服器擷取用戶端的cookie調用的方法:
request.getCookie()
傳回數組類型
伺服器設定cookie的生效時間:
伺服器擷取cookie的失效時間:cookie.setMaxAge(Integer.MAX_VALUE)
伺服器設定域名:cookie.getMaxAge()
伺服器設定路徑:cookie.setDomain(域名)
設定伺服器隻在SSL\HTTPS安全協定下傳送:cookie.setPath(路徑)
伺服器向用戶端設定/修改cookie的方法:cookie.setSecure(true)
修改隻能通過覆寫原來的cookieresponse.addCookie(Cookie cookie)
-
使用cookie需要注意:
1、cookie中使用Unicode字元時,需要對Unicode進行編碼,如使用中文;如果使用二進制,則需要使用BASE64進行編碼
2、cookie中可使用數字證書,提高安全性,但由于每次用戶端請求時頭部都會攜帶cookie,是以cookie值盡量精簡
3、修改、删除Cookie時,建立的Cookie除value、maxAge之外的所有屬性,例如name、path、domain等,都要與原Cookie完全一樣。否則,浏覽器将視為兩個不同的Cookie不予覆寫,導緻修改、删除失敗
4、domain參數必須以點(".")開始
-
cookie中的屬性
Name:cookie的名稱,一旦設定就不可進行更改
Value:cookie中name對應的value值
Domain:可通路該cookie的域名,如 .google.com,則所有以google.com結尾的域名都可通路該cookie值
Path:cookie的使用路徑,規定contextPath為特定,路徑的程式才可通路,如果設定為 ‘/’ ,則代表該域名下的contextPath都可通路
Expires / Max-Age:cookie失效的時間,機關為秒,預設值為-1,Max-Age>0時,浏覽器會将該cookie值持久化,儲存到相應的
cookie文檔當中去,除非到失效時間,否則浏覽器或者電腦關閉,cookie值也不會失效;Max-Age<0代表cookie為臨時值,cookie
值儲存到浏覽器記憶體中,一旦浏覽器關閉,cookie也會被清除;Max-Age=0代表删除該cookie值;
Secure:Cookie是否僅被使用安全協定傳輸,預設值為false,安全協定一般有ssl、HTTPS
comment:cookie的使用說明
version:該Cookie使用的版本号。0表示遵循Netscape的Cookie規範,1表示遵循W3C的RFC 2109規範
session的實作機制
-
session存儲客戶資訊的過程
用戶端通路伺服器,伺服器從session中查找相對應的用戶端資訊,如果沒有查詢到,伺服器會自動建立一個與用戶端資訊相對應的session值,存儲在記憶體中,并發送JSESSIONID(session的id)給用戶端,之後用戶端每次通路伺服器都會攜帶JSESSIONID,伺服器根據JSESSIONID值判斷用戶端的狀态,再将相對應的用戶端資訊傳回給伺服器,并更新session的最後通路時間
- 伺服器擷取session值的方法:
request.getSession()
如果不存在session,傳回null
伺服器擷取session值的方法:
getSession()
如果不存在session,則建立一個session,并傳回該session
讀用戶端的狀态:
寫用戶端資訊:session.getAttribute()
設定session的有效時間:session.setAttribute()
擷取session的有效時間:setMaxInactiveInterval(longinterval)
擷取session的所有屬性值:getMaxInactiveInterval()
getAttributeNames()
傳回一個枚舉類型
移出session屬性:
傳回session最後的活躍時間:removeAttribute(attribute)
擷取session的id值:getLastAccessedTime()
判斷session是否為建立的:HttpSession.getId()
URL位址重寫:isNew()
response.encodeURL(Stringurl)
-
使用session需要注意:
1、Session的使用比Cookie友善,但是過多的Session存儲在伺服器記憶體中,會對伺服器造成壓力
2、隻有通路JSP、Servlet等程式時才會建立Session,隻通路HTML、IMAGE等靜态資源并不會建立Session
3、隻要使用者通路了伺服器,就預設該使用者在伺服器存儲的session活躍了一次
4、重寫後的URL後面攜帶 “;jsessionid=XXX”
5、tomcat是根據請求的位址欄中是否帶有cookie,進而判斷浏覽器是否支援存儲cookie,對于第一次請求某浏覽器時,是不會攜帶cookie值的,這樣就導緻第一次請求的URL中會攜帶jsessionid值
6、大部分session機制都使用會話cookie來儲存session id,而關閉浏覽器後這個 session id就消失了,再次連接配接伺服器時也就無法找到原來的session
7、對于大多數不支援使用cookie機制的浏覽器,可直接禁止Session使用Cookie作為識别标志
-
采用URL重寫功能解決用戶端禁用cookie情況
用戶端将使用者session的id值重寫入URL中發送給伺服器,伺服器接收到URL後進行解析。擷取到相應的JSESSIONID值進行判斷,進而擷取到使用者的狀态
token的出現
如果使用者登陸了網站A,生成網站A相應的session值,再攜帶相關sessionId去通路僞造網站B,那麼網站B就可以竊取到使用者的資訊,進而利用資訊去通路網站A,進行一系列危害使用者的操作,為了解決這個問題,token由此誕生了。
token的生效機制
用戶端通路伺服器,伺服器會根據一定規則生成一個token值,并将token值通過cookie值存儲在響應頭傳回給用戶端,用戶端存儲cookie值,并在下次通路伺服器時攜帶包含token的cookie值,伺服器接收到cookie值,将cookie中的token與資料庫中存在的使用者資訊進行比對,比對成功則實作自動登入,并生成新的token值封裝進cookie中傳回給用戶端
- token的出現可解決
1、同源政策:即A網頁設定的cookie,B網頁無法打開,能夠使用同一cookie的網頁必須是同源的,即:協定相同、域名相同、接口相同
2、CSRF攻擊(Cross-site request forgery):跨站請求僞造,攻擊者盜用使用者的身份進行一系列危害使用者資訊、财産等操作
3、可在多個服務間共享
-
token失效時間的設定
方案一:伺服器存儲token狀态,使用者每操作一次,token的失效時間就重新整理一次(延遲),針對于一些前後端分離、單頁APP等會引起短時間多次請求重新整理,就會消耗大量資源,為了盡可能降低消耗,token的失效時間會存儲在記憶體或者緩存中
方案二:使用Refresh Token,可避免重複的讀寫操作。用戶端第一次發送請求給伺服器,伺服器校驗使用者身份,建立一個相比較token有效期更長的Refresh Token并關聯上token一起傳回給用戶端,用戶端之後發送請求,伺服器檢查token失效時間,如果已過期,将失效token發送給用戶端,用戶端發送Refresh Token重新申請Token,伺服器接收到Refresh Token并進行校驗,校驗成功,則生成一個新的token代替原來的token,并将新的token傳回給用戶端,用戶端再次攜帶新的token和請求資料請求伺服器
UUID
UUID是指在一台機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的