W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
當(dāng)激活 ?SessionMiddleware
?后,每個 ?HttpRequest
?對象(任何 Django 視圖函數(shù)的第一個參數(shù)) 將得到一個 ?session
?屬性,該屬性是一個類字典對象。
你可以在視圖中任意位置讀取它并寫入 ?request.session
? 。你可以多次編輯它。
這是所有會話對象的基礎(chǔ)類。它有以下標(biāo)準(zhǔn)字典方法:
__getitem__(key)
?:fav_color = request.session['fav_color']__setitem__(key, value)
?:request.session['fav_color'] = 'blue'__delitem__(key)
?:del request.session['fav_color'] 。如果給定的 key 不在會話里,會引發(fā) KeyError 。__contains__(key)
?:'fav_color' in request.sessionget(key, default=None)
?:fav_color = request.session.get('fav_color', 'red')pop(key, default=__not_given)
?:fav_color = request.session.pop('fav_color', 'blue')keys()
?items()
?setdefault()
?clear()
?它也有以下方法:
flush()
?:刪除當(dāng)前會話和會話cookie。如果你想確保早先的會話數(shù)據(jù)不能被用戶的瀏覽器再次訪問時,可以使用這個方法(比如,django.contrib.auth.logout() 函數(shù)調(diào)用它)。set_test_cookie()
?:設(shè)置一個測試cookie來確定用戶的瀏覽器是否支持cookie。由于測試通過,你不需要在下一個頁面請求時再次測試它。test_cookie_worked()
?:返回 True 或 False ,這取決于用戶瀏覽器是否接受測試cookie。由于 cookie 的工作方式,你將必須在上一個獨(dú)立的頁面請求里調(diào)用 set_test_cookie() 。delete_test_cookie()
?:刪除測試cookie。使用完測試cookie后用它來刪除。get_session_cookie_age()
?:返回 session cookies的失效時間,以秒為單位。默認(rèn) SESSION_COOKIE_AGE 。set_expiry(value)
?:為會話設(shè)置過期時間。你可以傳遞很多不同值:如果 value 是整型,會話將在閑置數(shù)秒后過期。比如,調(diào)用 ?request.session.set_expiry(300)
? 會使得會話在5分鐘后過期。如果 value 是一個 datetime 或 timedelta 對象,會話將在指定的 date/time 過期。注意,如果你正在使用 ?PickleSerializer
?,那么 datetime 和 timedelta 的值只能序列化。如果值為 0,則用戶的會話 cookie 將在用戶的 Web 瀏覽器關(guān)閉時過期。如果 value 是 None ,會話會恢復(fù)為全局會話過期策略。出于過期目的,讀取會話不被視為活動。會話過期時間會在會話最后一次*修改*后開始計算。get_expiry_age()
?:返回該會話過期的秒數(shù)。對于沒有自定義過期時間的會話(或者那些設(shè)置為瀏覽器關(guān)閉時過期的),這等同于 ?SESSION_COOKIE_AGE
?。這個函數(shù)接受兩個可選的關(guān)鍵參數(shù):?modification
?:會話的最后一次修改,當(dāng)做一個 datetime 對象。默認(rèn)是當(dāng)前時間。?expiry
?:會話的過期信息,如一個 datetime 對象,整數(shù)(秒)或 None。默認(rèn)為通過 set_expiry() 存儲在會話中的值,或 None 。get_expiry_date()
?:返回該會話的到期日期。對于沒有自定義過期的會話(或那些設(shè)置為在瀏覽器關(guān)閉時過期的會話),這將等于從現(xiàn)在開始的?SESSION_COOKIE_AGE
?秒的日期。這個函數(shù)接受與 get_expiry_age() 相同的參數(shù)。get_expire_at_browser_close()
?:返回 True 或 False,具體取決于用戶的 Web 瀏覽器關(guān)閉時用戶的會話 cookie 是否會過期。clear_expired()
?:從會話存儲中移除過期會話。這個類方法通過 ?clearsessions
?調(diào)用。cycle_key()
?:在保留當(dāng)前會話的同時創(chuàng)建新的會話秘鑰。?django.contrib.auth.login()
? 調(diào)用這個方法來防止會話固定攻擊。默認(rèn)情況下,Django 序列會話數(shù)據(jù)使用 JSON 。你可以設(shè)置 ?SESSION_SERIALIZER
?來自定義會話序列化格式。即使在編寫你自己的序列化程序中描述了警告,我們?nèi)匀粡?qiáng)烈建議您堅持JSON序列化,尤其是在您使用cookie后端的情況下。
比如,如果你使用 pickle 來序列化會話數(shù)據(jù),那么這里一個攻擊場景。如果你正在使用 ?signed cookie session backend
? 并且攻擊者已經(jīng)知道了 ?SECRET_KEY
?(Django 并不存在會導(dǎo)致其泄露的固有漏洞),攻擊者可以在會話里插入一個字符串,當(dāng) ?unpickled
?時,在服務(wù)器上執(zhí)行任意代碼。這樣做的技術(shù)很簡單,在互聯(lián)網(wǎng)上也很容易獲得。盡管cookie會話存儲會對cookie數(shù)據(jù)進(jìn)行簽名防止篡改,但是泄露 ?SECRET_KEY
?會立即升級為遠(yuǎn)程代碼執(zhí)行的漏洞。
來自 ?django.core.signing
? 的JSON序列化器的裝飾器??梢灾恍蛄谢緮?shù)據(jù)類型。
另外,因為JSON只支持字符串鍵,注意在 ?request.session
? 使用非字符串鍵會無法工作:
>>> # initial assignment
>>> request.session[0] = 'bar'
>>> # subsequent requests following serialization & deserialization
>>> # of session data
>>> request.session[0] # KeyError
>>> request.session['0']
'bar'
同樣,數(shù)據(jù)也不能在JSON中編碼,例如像 ?\xd9
? 這種非UTF8字節(jié)(會引發(fā) ?UnicodeDecodeError
?)不會被存儲。
支持任何Python對象,但是,如上所述,如果 ?SECRET_KEY
?泄露,這會導(dǎo)致攻擊者執(zhí)行遠(yuǎn)程代碼的漏洞。
注意這與 ?PickleSerializer
?不同,?JSONSerializer
?不會處理任何Python數(shù)據(jù)類型。通常情況下,便利性和安全性之間要做出權(quán)衡取舍。如果你想在 JSON 支持的會話里存儲任何高級數(shù)據(jù)類型(比如 ?datetime
?和 ?Decimal
?),你需要編寫自己的序列化器(或者在存儲這類值到 ?request.session
? 之前把它們轉(zhuǎn)化JSON序列化類型)。雖然序列化這些值通常很簡單( ?DjangoJSONEncoder
?或許有幫助),但編寫一個解碼器來可靠地取回你放進(jìn)去的東西就更不容易了。 例如,你要返回一個字符串格式的 ?datetime
?,但這恰好與為 ?datetime
?選擇的格式相同,這樣會有風(fēng)險。
你的序列化類必須實現(xiàn)兩個方法( ?dumps(self, obj)
?和? loads(self, data)
? ) 來分別進(jìn)行序列化和反序列化會話數(shù)據(jù)字典。
request.session
? 上使用普通的 Python 字符串作為字典鍵。這更多的是一種慣例而不是硬性規(guī)定。request.session
? ,不要訪問或設(shè)置它的屬性。像使用 Python 字典一樣使用它。這個簡單的視圖將一個 ?has_commented
?變量在用戶評論后設(shè)置為 ?True
?。它不允許用戶發(fā)表評論多于一次:
def post_comment(request, new_comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
這是一個記錄站點(diǎn)成員的簡單的視圖。
def login(request):
m = Member.objects.get(username=request.POST['username'])
if m.check_password(request.POST['password']):
request.session['member_id'] = m.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
這是記錄成員退出的視圖:
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
標(biāo)準(zhǔn)的 ?django.contrib.auth.logout()
? 函數(shù)實際上比這里要多一些來防止數(shù)據(jù)意外泄露。它調(diào)用 ?request.session
? 的 ?flush()
? 方法。我們使用這個例子作為示范如何使用會話對象,而不是完整的 ?logout()
? 實現(xiàn)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: