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