常量Flask会话ID
我有一个 Flask
应用程序,是通过 Nginx+WSGI(FastCGI 和 Gevent)来提供服务的,并且使用标准的 Flask 会话。我并没有使用 session.permanent=True
或其他额外的选项,只是简单地在默认配置中设置了 SECRET_KEY
。
我并没有在会话中保存任何(键,值)对,只是依靠 SID = session['_id']
这个条目来识别返回的用户。我使用以下代码来读取 SID
:
@page.route ('/')
def main (page='home', template='index.html'):
if not request.args.get ('silent', False):
print >> sys.stderr, "Session ID: %r" % session['_id']
我做了以下观察:
- 对于相同的 IP 地址,但不同的浏览器,我得到不同的
SIDs
- 这是可以预期的; - 对于不同的 IP 和相同的浏览器,我再次得到不同的
SIDs
- 也是可以预期的; - 对于相同的 IP 地址和相同的浏览器,我得到相同的
SID
- 这也是可以预期的;
现在,第三点很有趣,因为即使我 删除 了相应的 cookie,SID
仍然保持不变!在某种程度上,这也可以理解,但实际上我本来期待不同的 cookie 之间 SID
会有所变化。但我看到的唯一区别是
session.new is True
在删除 cookie 后的 第一次 请求中。即使这样也是非常可以预期的;但考虑到这些事实,我面临以下问题:
这是否意味着对于坐在 同一个 IP 后面的 不同 用户(使用相同的浏览器配置),我的后端会把他们误认为是 同一个 用户?
如果第一点不是这样,那么这些“粘性”会话的当前行为实际上是相当不错的,因为这避免了我的用户因为删除相应的 cookie 而丢失数据的情况。
他们仍然可以通过使用相同的浏览器从同一网络重新访问网站来挽救局面。我喜欢这样,但只有在第一点不是这样的时候。
我假设第一点实际上会让我遇到麻烦,结论是否应该是在会话中保存一个
token
,因此接受用户可以通过简单地删除他的 cookie 来“自毁”的命运?或者有没有办法告诉
Flask
为每个新 cookie 提供不同的SIDs
?
实际上,这个问题是因为我使用了一个负载测试服务,它模拟了 不同 用户(在同一个 IP 上),但我的后端一直把他们视为同一个用户,因为相应的 SIDs
都是相同的。
这个应用程序可以在 http://webed.blackhan.ch 上进行测试(发布后将移至 https://notex.ch [一个基于浏览器的文本编辑器])。感谢你的回答。
3 个回答
现在是2022年,Flask-Session确实支持通过session.sid
来获取一个生成的UUID,这个UUID看起来像这样:
print(session.sid)
>>> f9c792fa-70e0-46e3-b84a-3a11813468ce
来自官方文档(https://flasksession.readthedocs.io/en/latest/)
sid
会话ID,我们内部使用uuid.uuid4()来生成一个会话ID。你可以通过session.sid来访问它。
看起来你在使用Flask-Login这个扩展。这里是生成id令牌的代码:
def _create_identifier():
base = unicode("%s|%s" % (request.remote_addr,
request.headers.get("User-Agent")), 'utf8', errors='replace')
hsh = md5()
hsh.update(base.encode("utf8"))
return hsh.digest()
其实就是 md5(ip_address + user_agent)
的结果。
Flask使用Werkzeug的安全cookie来存储这个标识符。安全cookie顾名思义就是比较安全的:
这个模块实现了一种客户端无法修改的cookie,因为它添加了一个服务器会检查的校验和。如果你只有用户id或者其他标记已登录用户的东西,可以用它来替代会话。