COOKIE與SESSION簡介:
1、cookie不屬于http協定範圍,由于http協定無法保持狀态,但實際情況,我們卻又需要‘保持狀态’,是以cookie就是在這個場景下誕生。
cookie的工作原理是:由伺服器産生内容,浏覽器收到請求後儲存在本地;當浏覽器再次通路時,浏覽器會自動帶上cookie,這樣伺服器就能通過cookie的内容來判斷這個是 “誰”。
2、cookie雖然在一定程度上解決了‘保持狀态’的需求,但是由于cookie本身最大支援4096位元組,以及cookie本身儲存在用戶端,可能被攔截或竊取,是以就需要有一種新的東西,它能支援更多的位元組,并且他儲存在伺服器,有較高的安全性。這就是session。
問題來了,基于http協定的無狀态特性,伺服器根本就不知道通路者是‘誰’。那麼上述的cookie就起到橋接的作用。
我們可以給每隔用戶端的cookie配置設定一個唯一的id,這樣使用者在通路時,通過cookie,伺服器就知道來的人是‘誰’。然後我們再根據不同的cookie的id,在伺服器上儲存一段時間的私密資料,如“帳号密碼”等。
3、總結而言:cookie彌補了http無狀态的不足,讓伺服器知道來的人是“誰”;但是cookie以文本的形式儲存在本地,自身安全性比較差,是以我們就通過cookie識别不同的使用者,對應的在session裡儲存私密的資訊以及超過4096位元組的文本。
4、另外、上述cookie和session是共同性的東西,不限于語言和架構
認證應用
前幾節的介紹中我們已經有能力制作一個登陸頁面,在驗證了使用者名和密碼的正确性後跳轉到背景的頁面。但是測試後也發現,如果繞過登陸頁面。直接輸入背景的url位址也可以直接通路的。這個顯然是不合理的。其實我們缺失的就是cookie和session配合的驗證。有了這個驗證過程,我們就可以實作和其他網站一樣必須登入才能進入背景頁面了。
先說一下這種認證的機制。每當我們使用一款浏覽器通路一個登陸頁面的時候,一旦我們通過了認證。伺服器端就會發送一組随機唯一的字元串(假設是123abc)到浏覽器端,這個被存儲在浏覽端的東西就叫cookie。而伺服器端也會自己存儲一下使用者目前的狀态,比如login=true,username=hahaha之類的使用者資訊。但是這種存儲是以字典形式存儲的,字典的唯一key就是剛才發給使用者的唯一的cookie值。那麼如果在伺服器端檢視session資訊的話,理論上就會看到如下樣子的字典
{'123abc':{'login':true,'username:hahaha'}}
因為每個cookie都是唯一的,是以我們在電腦上換個浏覽器再登陸同一個網站也需要再次驗證。那麼為什麼說我們隻是理論上看到這樣子的字典呢?因為處于安全性的考慮,其實對于上面那個大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在伺服器端也是一樣被加密的。是以我們伺服器上就算打開session資訊看到的也是類似與以下樣子的東西
{'123abc':dasdasdasd1231231da1231231}
Cookie是什麼?
儲存在用戶端浏覽器上的鍵值對
Session是什麼?
儲存在服務端的資料(本質是鍵值對) 應用:依賴cookie ; 作用:保持會話(web網站); 好處:敏感資訊不會直接給用戶端
如下測試session 驗證代碼:
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def test(request):
# models.UserInfo.objects.create(username='root',email='qweqweq')
# models.UserInfo.objects.create(username='xxx',email='xxx',ctime='2011-11-11')
# return HttpResponse('...')
# v = {'k1':'v1','k2':'v2'}
# for i in v.values():
#
# return render(request,'test.html',{'name':'fangsaowei'})
response = HttpResponse('内容')
response.set_cookie('k1','v1')
response.set_cookie('k2','v2')
response.set_cookie('k3','v3')
response.set_cookie('k4','v4')
return response
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
u = request.POST.get('user')
p = request.POST.get('pwd')
obj = models.UserAdmin.objects.filter(username=u,password=p).first()
if obj:
# 1. 生成随機字元串
# 2. 通過cookie發送給用戶端
# 3. 服務端儲存
# {
# 随機字元串1: {'username':'alex','email':x''...}
# }
request.session['username'] = obj.username
return redirect('/index/')
else:
return render(request,'login.html',{'msg':'使用者名或密碼錯誤'})
def index(request):
# 1. 擷取用戶端端cookie中的随機字元串
# 2. 去session中查找有沒有随機字元
# 3. 去session對應key的value中檢視是否有 username
v = request.session.get('username')
if v:
return HttpResponse('登入成功:%s' %v)
else:
return redirect('/login/')
Django中Cookie和Session補充:
Cookie
1、擷取Cookie:
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
參數:
default: 預設值
salt: 加密鹽
max_age: 背景控制過期時間
2、設定Cookie:
rep = HttpResponse(...) 或 rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密鹽',...)
參數:
key, 鍵
value='', 值
max_age=None, 逾時時間
expires=None, 逾時時間(IE requires expires, so set it if hasn't been already.)
path='/', Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie可以被任何url的頁面通路
domain=None, Cookie生效的域名
secure=False, https傳輸
httponly=False 隻能http協定傳輸,無法被JavaScript擷取(不是絕對,底層抓包可以擷取到也可以被覆寫)
由于cookie儲存在用戶端的電腦上,是以,JavaScript和jquery也可以操作cookie。
<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });
Session
Django中預設支援Session,其内部提供了5種類型的Session供開發者使用:
- 資料庫(預設)
- 緩存
- 檔案
- 緩存+資料庫
- 加密cookie
1、資料庫Session
Django預設支援Session,并且預設是将Session資料存儲在資料庫中,即:django_session 表中。
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(預設)
SESSION_COOKIE_NAME = "sessionid" # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串(預設)
SESSION_COOKIE_PATH = "/" # Session的cookie儲存的路徑(預設)
SESSION_COOKIE_DOMAIN = None # Session的cookie儲存的域名(預設)
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(預設)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie隻支援http傳輸(預設)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(預設)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉浏覽器使得Session過期(預設)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都儲存Session,預設修改之後才儲存(預設)
b. 使用
def index(request):
# 擷取、設定、删除Session中資料
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在則不設定
del request.session['k1']
# 所有 鍵、值、鍵值對
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# 使用者session的随機字元串
request.session.session_key
# 将所有Session失效日期小于目前日期的資料删除
request.session.clear_expired()
# 檢查 使用者session的随機字元串 在資料庫中是否
request.session.exists("session_key")
# 删除目前使用者的所有Session資料
request.session.delete("session_key")
request.session.set_expiry(value)
* 如果value是個整數,session會在些秒數後失效。
* 如果value是個datatime或timedelta,session就會在這個時間後失效。
* 如果value是0,使用者關閉浏覽器session就會失效。
* 如果value是None,session會依賴全局session失效政策。
View Code
2、緩存Session
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的緩存别名(預設記憶體緩存,也可以是memcache),此處别名依賴緩存的設定
SESSION_COOKIE_NAME = "sessionid" # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串
SESSION_COOKIE_PATH = "/" # Session的cookie儲存的路徑
SESSION_COOKIE_DOMAIN = None # Session的cookie儲存的域名
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie隻支援http傳輸
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉浏覽器使得Session過期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都儲存Session,預設修改之後才儲存
b. 使用
同上
3、檔案Session
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 緩存檔案路徑,如果為None,則使用tempfile子產品擷取一個臨時位址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
SESSION_COOKIE_NAME = "sessionid" # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串
SESSION_COOKIE_PATH = "/" # Session的cookie儲存的路徑
SESSION_COOKIE_DOMAIN = None # Session的cookie儲存的域名
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie隻支援http傳輸
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉浏覽器使得Session過期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都儲存Session,預設修改之後才儲存
b. 使用
同上
4、緩存+資料庫Session
資料庫用于做持久化,緩存用于提高效率
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
b. 使用
同上
5、加密cookie Session
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
b. 使用
同上
def login(func):
def wrap(request, *args, **kwargs):
# 如果未登陸,跳轉到指定頁面
if request.path == '/test/':
return redirect('http://www.baidu.com')
return func(request, *args, **kwargs)
return wrap