当激活 SessionMiddleware
后,每个 HttpRequest
对象(任何 Django 视图函数的第一个参数) 将得到一个 session
属性,该属性是一个类字典对象。
你可以在视图中任意位置读取它并写入 request.session
。你可以多次编辑它。
这是所有会话对象的基础类。它有以下标准字典方法:
__getitem__(key)
:fav_color = request.session["fav_color"]__setitem__(key, value)
:request.session["fav_color"] = "blue"__delitem__(key)
:del request.session["fav_color"] 。如果给定的 key 不在会话里,会引发 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()
:删除当前会话和会话cookie。如果你想确保早先的会话数据不能被用户的浏览器再次访问时,可以使用这个方法(比如,django.contrib.auth.logout() 函数调用它)。set_test_cookie()
:设置一个测试cookie来确定用户的浏览器是否支持cookie。由于测试通过,你不需要在下一个页面请求时再次测试它。test_cookie_worked()
:返回 True 或 False ,这取决于用户浏览器是否接受测试cookie。由于 cookie 的工作方式,你将必须在上一个独立的页面请求里调用 set_test_cookie() 。delete_test_cookie()
:删除测试cookie。使用完测试cookie后用它来删除。get_session_cookie_age()
:返回 session cookies的失效时间,以秒为单位。默认 SESSION_COOKIE_AGE 。set_expiry(value)
:为会话设置过期时间。你可以传递很多不同值:如果 value 是整型,会话将在闲置数秒后过期。比如,调用 request.session.set_expiry(300)
会使得会话在5分钟后过期。如果 value 是一个 datetime 或 timedelta 对象,会话将在指定的 date/time 过期。注意,如果你正在使用 PickleSerializer
,那么 datetime 和 timedelta 的值只能序列化。如果值为 0,则用户的会话 cookie 将在用户的 Web 浏览器关闭时过期。如果 value 是 None ,会话会恢复为全局会话过期策略。出于过期目的,读取会话不被视为活动。会话过期时间会在会话最后一次*修改*后开始计算。get_expiry_age()
:返回该会话过期的秒数。对于没有自定义过期时间的会话(或者那些设置为浏览器关闭时过期的),这等同于 SESSION_COOKIE_AGE
。这个函数接受两个可选的关键参数:modification
:会话的最后一次修改,当做一个 datetime 对象。默认是当前时间。expiry
:会话的过期信息,如一个 datetime 对象,整数(秒)或 None。默认为通过 set_expiry() 存储在会话中的值,或 None 。get_expiry_date()
:返回该会话的到期日期。对于没有自定义过期的会话(或那些设置为在浏览器关闭时过期的会话),这将等于从现在开始的SESSION_COOKIE_AGE
秒的日期。这个函数接受与 get_expiry_age() 相同的参数。get_expire_at_browser_close()
:返回 True 或 False,具体取决于用户的 Web 浏览器关闭时用户的会话 cookie 是否会过期。clear_expired()
:从会话存储中移除过期会话。这个类方法通过 clearsessions
调用。cycle_key()
:在保留当前会话的同时创建新的会话秘钥。django.contrib.auth.login()
调用这个方法来防止会话固定攻击。默认情况下,Django 序列会话数据使用 JSON 。你可以设置 SESSION_SERIALIZER
来自定义会话序列化格式。即使在编写你自己的序列化程序中描述了警告,我们仍然强烈建议您坚持JSON序列化,尤其是在您使用cookie后端的情况下。
比如,如果你使用 pickle 来序列化会话数据,那么这里一个攻击场景。如果你正在使用 signed cookie session backend
并且攻击者已经知道了 SECRET_KEY
(Django 并不存在会导致其泄露的固有漏洞),攻击者可以在会话里插入一个字符串,当 unpickled
时,在服务器上执行任意代码。这样做的技术很简单,在互联网上也很容易获得。尽管cookie会话存储会对cookie数据进行签名防止篡改,但是泄露 SECRET_KEY
会立即升级为远程代码执行的漏洞。
来自 django.core.signing
的JSON序列化器的装饰器。可以只序列化基本数据类型。
另外,因为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"
同样,数据也不能在JSON中编码,例如像 xd9
这种非UTF8字节(会引发 UnicodeDecodeError
)不会被存储。
支持任何Python对象,但是,如上所述,如果 SECRET_KEY
泄露,这会导致攻击者执行远程代码的漏洞。
注意这与 PickleSerializer
不同,JSONSerializer
不会处理任何Python数据类型。通常情况下,便利性和安全性之间要做出权衡取舍。如果你想在 JSON 支持的会话里存储任何高级数据类型(比如 datetime
和 Decimal
),你需要编写自己的序列化器(或者在存储这类值到 request.session
之前把它们转化JSON序列化类型)。虽然序列化这些值通常很简单( DjangoJSONEncoder
或许有帮助),但编写一个解码器来可靠地取回你放进去的东西就更不容易了。 例如,你要返回一个字符串格式的 datetime
,但这恰好与为 datetime
选择的格式相同,这样会有风险。
你的序列化类必须实现两个方法( dumps(self, obj)
和 loads(self, data)
) 来分别进行序列化和反序列化会话数据字典。
request.session
上使用普通的 Python 字符串作为字典键。这更多的是一种惯例而不是硬性规定。request.session
,不要访问或设置它的属性。像使用 Python 字典一样使用它。这个简单的视图将一个 has_commented
变量在用户评论后设置为 True
。它不允许用户发表评论多于一次:
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!")
这是一个记录站点成员的简单的视图。
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.")
标准的 django.contrib.auth.logout()
函数实际上比这里要多一些来防止数据意外泄露。它调用 request.session
的 flush()
方法。我们使用这个例子作为示范如何使用会话对象,而不是完整的 logout()
实现。
安装Python作为一个 Python 网络框架,Django 需要 Python。Python 包含了一个名为 SQLite 的轻量级数据库,所以你暂时不必自行...
在后台,Django将如何以及在哪里存储文件的决策委托给文件存储系统。这个对象实际上理解文件系统、打开和读取文件等。Django 的...
下表列出了JTextComponent类中包含的某些常用的文本组件方法。...我们可以根据两个标准对文本组件进行分类:number of lines in t...
Java Swing教程 -Java Swing外观和感觉Swing支持可插拔的外观(L F)。Swing支持可插拔的外观(L F)。...lafClassName参数是提供L F...
对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用需要项目中已注入对应...
MyBatis-Plus 条件构造器-AbstractWrapperisNotNull(R column)isNotNull(boolean condition, R column)字段ISNOTNULL例:isNotN...
属性(properties)这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的Java属性文件中配置这些属性,也可以在pr...
Spring教程 -Spring表达式语言使用数据库属性文件...bean.property_name在下面的代码中,我们从“addressBean"注入了“country"...
Spring JSR-250 注释Spring还使用基于 JSR-250 注释,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释。因为你已经有了...