ython django框架中cookie使用
1.簡述
(1)設置Cookies
response.set_cookie("cookie_key","value")
(2)獲取Cookies
value=request.COOKIES["cookie_key"]
(3)刪除Cookies
response.delete_cookie("cookie_key",path="/",domain=name)
(4)檢測Cookies
if "cookie_name" in request.COOKIES :
(5)response.set_cookie()
傳遞一些可選的參數 描述
2.示例
2.1設置Cookies
login_user=models.User.objects.get(username=username, password=password) # 這里用的mongodb進行的數據存儲 # print(login_user["username"]) # 帳號和密碼正確,cookie保存登錄狀態 # 獲取相應對象 response=redirect(reverse("blog:index")) # 設置cookie response.set_cookie("blog_username", login_user["username"], 604800) #過期時間單位是s (這里設置為7天) response.set_cookie("blog_password", login_user["password"], 604800)
2.2檢測、獲取Cookies
def index(request): # 檢測cookies是否存在 if "blog_username" in request.COOKIES: # 獲取cookies login_username=request.COOKIES.get("blog_username") login_password=request.COOKIES.get("blog_password") # 獲取登錄用戶信息 login_user=models.User.objects.get(username=login_username, password=login_password) # 返回登錄成功后頁面 return render(request, "blog/index.html", {"login_user": login_user}) else: # 進入未登錄狀態的主頁 return render(request, "blog/index.html")
2.3刪除Cookies
大家詳細了解下Cookie相關的知識!
一、背景
HTTP無狀態:服務器無法知道兩個請求是否來自同一個瀏覽器,即服務器不知道用戶上一次做了什么,每次請求都是完全相互獨立。早期互聯網只是用于簡單的瀏覽文檔信息、查看黃頁、門戶網站等等,并沒有交互這個說法。但是隨著互聯網慢慢發展,寬帶、服務器等硬件設施已經得到很大的提升,互聯網允許人們可以做更多的事情,所以交互式Web慢慢興起,而HTTP無狀態的特點卻嚴重阻礙其發展!
二、Cookie是什么東東
Cookie是由服務器發給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端,然后客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息,用于服務器記錄客戶端的狀態。
Cookie主要用于以下三個方面:
三、Cookie原理
在了解了Cookie是由服務器發出存儲在瀏覽器的特殊信息,那具體是怎么樣的一個過程呢?為大家為大家畫了一幅Cookie原理圖。
用戶在輸入用戶名和密碼之后,瀏覽器將用戶名和密碼發送給服務器,服務器進行驗證,驗證通過之后將用戶信息加密后封裝成Cookie放在請求頭中返回給瀏覽器。
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg; Expires=Tue, 15 Aug 2019 21:47:38 GMT; Path=/; Domain=.169it.com; HttpOnly
瀏覽器收到服務器返回數據,發現請求頭中有一個:Set-Cookie,然后它就把這個Cookie保存起來,下次瀏覽器再請求服務器的時候,會把Cookie也放在請求頭中傳給服務器:
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg
服務器收到請求后從請求頭中拿到cookie,然后解析并到用戶信息,說明此用戶已登錄,Cookie是將數據保存在客戶端的。用戶信息是保存在Cookie中,也就相當于是保存在瀏覽器中,那就說用戶可以隨意修改用戶信息,是一種不安全的策略!強調一點:Cookie無論是服務器發給瀏覽器還是瀏覽器發給服務器,都是放在請求頭中的!
四、Cookie屬性
一個Cookie有:Name、Value、Domain、Path、Expires/Max-Age、Size、HTTP、Secure這些屬性,那這些屬性分別都有什么作用呢?
1、Name&Value
Name表示Cookie的名稱,服務器就是通過name屬性來獲取某個Cookie值。Value表示Cookie 的值,大多數情況下服務器會把這個value當作一個key去緩存中查詢保存的數據。
2、Domain&Path
Domain表示可以訪問此cookie的域名,以百度貼吧Cookie來講解一下Domain屬性。
從上圖中我們可以看出domain有:.baidu.com 頂級域名和.teiba.baidu.com的二級域名,所以這里就會有一個訪問規則:頂級域名只能設置或訪問頂級域名的Cookie,二級及以下的域名只能訪問或設置自身或者頂級域名的Cookie,所以如果要在多個二級域名中共享Cookie的話,只能將Domain屬性設置為頂級域名!
3、Expires/Max-Age
Expires/Max-Age表示此cookie超時時間。若設置其值為一個時間,那么當到達此時間后,此cookie失效。不設置的話默認值是Session,意思是cookie會和session一起失效。當瀏覽器關閉(不是瀏覽器標簽頁,而是整個瀏覽器) 后,此cookie失效,當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,而不是服務端。
4、Size
Size表示Cookie的name+value的字符數,比如有一個Cookie:id=666,那么Size=2+3=5 。
另外每個瀏覽器對Cookie的支持都不相同
5、HTTP
HTTP表示cookie的httponly屬性。若此屬性為true,則只有在http請求頭中會帶有此cookie的信息,而不能通過document.cookie來訪問此cookie。
6、Secure
Secure表示是否只能通過https來傳遞此條cookie。不像其它選項,該選項只是一個標記并且沒有其它的值。這種cookie的內容意指具有很高的價值并且可能潛在的被破解以純文本形式傳輸。
五、操作Cookie
1、生成Cookie
Cookie是由服務端生成的,那如何用Python代碼來生成呢?
從登錄代碼中我們看到,在簡單的驗證用戶名和密碼之后,服務器跳轉到/user,然后set了一個cookie,瀏覽器收到響應后發現請求頭中有一個:Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg,然后瀏覽器就會將這個Cookie保存起來!
2、獲取Cookie
用requests模塊來獲取Cookie。
r.cookies表示獲取所有cookie,get_dict()函數表示返回的是字典格式cookie。
3、設置Cookie
用瀏覽器復制過來的Cookie放在代碼中,這樣便可以順利的偽裝成瀏覽器,然后正常爬取數據,復制Cookie是爬蟲中常用的一種手段!
六、Session
1、背景
其實在Cookie設計之初Cookie只保存一個key,而是直接保存用戶信息,剛開始大家認為這樣用起來很爽,但是由于cookie 是存在用戶端,而且它本身存儲的尺寸大小也有限,最關鍵是用戶可以是可見的,并可以隨意的修改,很不安全。那如何又要安全,又可以方便的全局讀取信息呢?于是,這個時候,一種新的存儲會話機制:Session 誕生了。
2、Session是什么
Session翻譯為會話,服務器為每個瀏覽器創建的一個會話對象,瀏覽器在第一次請求服務器,服務器便會為這個瀏覽器生成一個Session對象,保存在服務端,并且把Session的Id以cookie的形式發送給客戶端瀏覽,而以用戶顯式結束或session超時為結束。
Session工作原理:
對于session標識號(sessionID),有兩種方式實現:Cookie和URL重寫,Session原理圖。
Cookie是將數據直接保存在客戶端,而Session是將數據保存在服務端,就安全性來講Session更好!
七、總結
1、Cookie和Session關系
2、Cookie帶來的安全性問題
、誕生背景
HTTP是無狀態的,即服務器無法知道兩個請求是否來自同一個瀏覽器,也就是服務器不知道用戶上一次做了什么,每次請求都是完全獨立的。
早期互聯網只是用于簡單的瀏覽文檔信息、查看黃頁和門戶網站等,并沒有交互這個概念。但是隨著互聯網慢慢發展,寬帶、服務器等硬件設施得到了很多的提升,互聯網允許人們做更多的事情,所以交互式Web(交互式Web即客戶端與服務器可以互動,如用戶登錄、商品購買和論壇等)慢慢就興起了,而HTTP無狀態的特點對此造成了嚴重阻礙。
由于不能記錄用戶上次的操作,偉大的程序員發明了隱藏域用于記錄用戶上一次的操作信息;通過隱藏域把用戶上次操作記錄放在form表單的input中,這樣請求時將表單提交就可以知道上一次用戶的操作了,但是這樣每次都得創建隱藏域而且需要賦值,既麻煩又容易出錯;但是隱藏域作用強大,時至今日都有很多人在用它解決各種問題。隱藏域的寫法如下:
<input type="hidden" name="field_name" value="value">
網景公司的盧-蒙特利Lou Montulli,在1994年將Cookies的概念應用于網絡通信,用于解決用戶網上購物的購物車歷史記錄,而當時最強大的瀏覽器也是網景瀏覽器;之后在網景瀏覽器的支持下其他瀏覽器也逐漸開始支持Cookie,到如今所有瀏覽器都支持Cookie了。
二、什么是Cookie
Cookie的誕生是為了解決HTTP無狀態的特性,用于滿足交互式Web。
圖1. Chrome瀏覽器百度首頁Cookies
圖2. Firefox瀏覽器百度首頁Cookie
圖3. Safari瀏覽器百度首頁Cookie
上圖中可以看到在Chrome、Firefox和Safari瀏覽器中百度首頁的Cookie,在表格中,每一行都代表著一個Cookie。Cookie是由服務器發給客戶端的特殊信息,而這些信息以文本文件的形式存儲在客戶端,然后客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息,用于服務器記錄客戶端的狀態。
Cookie主要運用于以下三個方面:
1、會話狀態管理,如用戶登錄狀態、購物車、游戲分數或其他需要記錄的信息;
2、個性化設置,如用戶自定義設置、主題等;
3、瀏覽器行為跟蹤。
三、Cookie原理
Cookie是由服務器發出存儲在瀏覽器的特殊信息,其具體的過程可以通過一個用戶登錄的例子來了解。
圖4. Cookie工作原理
如上圖所示,用戶在輸入用戶名和密碼之后,瀏覽器將用戶名和密碼發送給服務器,服務器進行驗證,驗證通過后將用戶信息加密后封裝成Cookie放在請求頭中返回給瀏覽器。
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg; Expires=Tue, 15 Aug 2019 21:47:38 GMT; Path=/; Domain=.169it.com; HttpOnly [響應體]
瀏覽器收到服務器返回的數據,發現請求頭中有一個:Set-Cookie,然后它就把這個Cookie保存起來,下次瀏覽器再請求服務器的時候,會把Cookie也一起放在請求頭中傳給服務器。
GET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg
服務器收到請求后從請求頭中拿到Cookie,然后解析并得到用戶信息,說明此用戶已登錄,因此Cookie是將數據保存在客戶端的。
從上述用戶登錄的例子可以看出,用戶信息是保存在Cookie中,也就相當于是保存在瀏覽器中的,那么用戶就可以隨意更改用戶信息,這是一種不安全的策略。另外,Cookie無論是服務器發送給瀏覽器,還是瀏覽器發送給服務器,都是放在請求頭中的。
四、Cookie屬性
從上圖的Chorme、Firefox和Safari瀏覽器可以看到一個Cookie有:Name、Value、Domian、Path、Expires/Max-Age、Size、Http(Httponly)和Secure這些屬性。
1、Name & Value
Name表示Cookie的名稱,服務器就是通過name屬性來獲取某個Cookie的值。
Value表示Cookie的值,多數情況下服務器會把這個value當做一個Key去緩存中查詢保存的數據。
2、Domain & Path
Domian表示可以訪問此Cookie的域名,下圖我們以百度貼吧首頁的Cookie來了解下Domain的屬性。
圖5. Chrome瀏覽器貼吧首頁Cookie's Domain
圖中可以看出,第三列的Domian有:.baidu.com頂級域名和.teiba.baidu.com二級域名;所以這里就有一個訪問規則:頂級域名只能設置或訪問頂級域名的Cookie,二級以下的域名只能訪問或設置自身或者頂級域名的Cookie,所以如果要在多個二級域名中共享Cookie的話,只能將Domain的屬性設置為頂級域名。
Path表示可以訪問此Cookie的頁面路徑;如path=/test,那么只有/test路徑下的頁面可以讀取此Cookie。
3、Expire/Max-Age
Expire/Max-Age表示此cookie的超時時間;若設置其值為一個時間,那么當到達此時間后,此cookie則會失效;不設置的話默認值是Session,意思是cookie會和session一起失效;當瀏覽器關閉(關閉整個瀏覽器,而不是瀏覽器的標簽頁)后,此cookie失效。另外,當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,與服務端無關。
4、Size
Size表示Cookie的name+value的字符數,比如有一個Cookie:id=666,那么Size=2+3=5。2即是name,3即為value,各個瀏覽器對Cookie的支持都有所不同,如下圖:
圖6. 各瀏覽器Cookie支持的個數
5、HTTP
HTTP表示cookie的httponly屬性;若此屬性為true,則只有在http請求頭中會帶有此cookie的信息,而不能通過document.cookie來訪問此cookie。這么設計是為了提供一個安全措施來幫助阻止通過JavaScript發起的跨站腳本攻擊(XXS)竊取cookie的惡劣行為。
圖7. document.cookie
6、Secure
Secure表示是否只能通過https來傳遞此條cookie;不像其他選項,該選項只是一個標記并且沒有其他的值。
五、Java操作Cookie
1、生成Cookie
1 package com.ausclouds.bdbsec.auth.cmb; 2 3 import javax.servlet.http.Cookie; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 public class CookieServlet extends HttpServlet { 9 10 @Override 11 protected void service(HttpServletRequest req, HttpServletResponse resp){ 12 //創建Cookie對象 13 Cookie comCookie=new Cookie("computer", "HP"); 14 //服務器把cookie響應給客戶端,所有的cookie對象,都會在服務器端創建,通過http響應給客戶端(瀏覽器) 15 16 //如果不設置使用時間,則取不到Cookie的值 17 comCookie.setMaxAge(60*60*24*30); 18 19 //一旦設置了cookie的路徑,就只能通過這一個路徑才能獲取到cookie的信息 20 comCookie.setPath(req.getContextPath() + "/getCookie.sxt"); 21 22 //添加cookie 23 resp.addCookie(comCookie); 24 25 } 26 }
2、獲取Cookie
1 package com.ausclouds.bdbsec.auth.cmb; 2 3 import javax.servlet.http.Cookie; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 public class GetCookieServlet extends HttpServlet { 9 10 @Override 11 protected void service(HttpServletRequest req, HttpServletResponse resp){ 12 //獲取cookie信息 13 Cookie[] cookies=req.getCookies(); 14 for (int i=0; i<cookies.length; i++){ 15 System.out.println(cookies[i].getName() + ":" + cookies[i].getValue()); 16 } 17 } 18 19 }
3、刪除Cookie
//刪除Cookie的思路就是替換原來的cookie,并設置它的生存時間為0 Cookie cookie=new Cookie("Cookie",null);//cookie名字要相同 cookie.setMaxAge(0); // cookie.setPath(request.getContextPath()); // 相同路徑 response.addCookie(cookie);
六、Session
1、誕生背景
其實設計Cookie之初,它并不是僅僅保存了一個key值,而是直接保存用戶的信息,但是由于cookie是存在客戶端的,而且本身存儲的尺寸大小也是有限的,最關鍵的是用戶是可見的,并且可以隨意地修改,這相當地不安全。為了既安全又方便的讀取全局信息,于是誕生了Session這種新的存儲會話機制。
2、什么是Session
Session翻譯為會話,服務器為每個瀏覽器創建一個會話對象,瀏覽器在第一次請求服務器時,服務器便會為該瀏覽器生成一個Seesion對象,保存在服務端,并且把Session的Id以cookie的形式發送給客戶端瀏覽器,最終以用戶顯示結束或session超時為結束。
Session工作原理:
1.當某個用戶向服務器發送第一個請求時,服務器為其建立一個sesion,并為此session創建一個標識號(sessionID);
2.這個用戶隨后的所有請求都應包括這個標識號(sessionID),服務器會校對這個標識號以判斷請求是屬于哪個session的;
3.sessionID標識號有兩種實現方式:Cookie和URL重寫;
4.Cookie是將數據直接保存在客戶端,而Session是將數據保存在服務端,所以Session的安全性更佳。
圖8. Session工作原理(基于Cookie實現)
3、Java操作Session
1.創建Session
ActionContext actionContext=ActionContext.getContext(); Map<String, Object> mapSession=actionContext.getSession(); mapSession.put("branch", branch); mapSession.put("permission", per);
2.JSP獲取Session
1 if(session.getAttribute("branch")==null||session.getAttribute("permission")==null) 2 { 3 response.setCharacterEncoding("utf-8"); 4 out.print("<script>alert('您還沒有登錄,請登錄') </script>"); 5 out.flush(); 6 out.close(); 7 }
3.Java后臺獲取Session
1 ActionContext actionContext=ActionContext.getContext(); 2 Map session=actionContext.getSession(); 3 String inputUserid=(String)session.get("username"); 4 String proving=(String)session.get("proving");
七、面試相關
1、Cookie和Session的關系?
1. 二者都是為實現客戶端與服務端交互而服務的;
2. Cookie是保存在客戶端,缺點易偽造、不安全;
3. Session是保存在服務端,會消耗服務器資源;
4. Session實現有兩種方式:Cookie和URL重寫。
2、Cookie帶來的安全性問題?
1. 會話劫持和XSS:在Web應用中,Cookie常用來標記用戶或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權用戶的會話受到攻擊;常用的竊取Cookie的方式有社會工程學攻擊和應用程序漏洞進行XSS攻擊;
2. 跨站請求偽造(CSRF):維基百科已經給出了一個較好的CSRF例子。如在不安全的聊天室或論壇上的一張圖片,它實際上是一個給你銀行服務器發送提現的請求:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
當你點擊打開該圖片時,如果之前已經登錄過你的銀行賬號并且Cookie仍未失效,那么你銀行里的錢很可能會被自動轉走;解決CSRF的辦法有:隱藏域驗證碼、確認機制和設置較短的Cookie生命周期等。
3、Session應用場景?
Session主要是服務器端存儲,用來描述一些用戶信息或者相關的其他數據,還可以是其他類型的數據,只要是你的業務覺得可以綁定到用戶或客戶端的相關數據都可以放到session中;最基本的場景就是存儲登錄用戶信息。
4、Session生命周期?
1、創建:若訪問的第一個資源是JSP頁面,則創建session對象;若訪問的第一個資源是Servlet,則需要手動調用request.getSession()方法來創建session對象;
2、銷毀:調用session.invalidate()方法來銷毀session()對象,session會話超時默認30分鐘。
最后我自己是一名從事了多年開發的JAVA老程序員,今年年初我花了一個月整理了一份最適合2019年學習的java學習干貨,我想分享給每一位喜歡java的小伙伴,想要獲取的可以關注我并在后臺私信我:01,即可免費獲取。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。