如何正确、安全地处理Python中的cookie和会话';谁的烧瓶?

如何正确、安全地处理Python中的cookie和会话';谁的烧瓶?,python,security,session,cookies,flask,Python,Security,Session,Cookies,Flask,在我编写的应用程序中,我一直在用户浏览器中保存一个cookie,其中存储了会话ID,该ID被用作对存储在数据库中的会话的引用,该数据库包含用户信息,包括用户是否正确登录的事实 我想回顾一下我的解决方案的安全性,并开始研究我应该如何在登录时设置cookies,在服务器端存储的会话中存储什么,以及如何在注销时销毁这些信息,因为到目前为止,我的用户登录已久,这不是我的意图 我的问题是如何在Flask中正确处理整个用户登录/会话/注销问题没有明确的答案-一些人在谈论使用Flask的响应。删除\u coo

在我编写的应用程序中,我一直在用户浏览器中保存一个cookie,其中存储了会话ID,该ID被用作对存储在数据库中的会话的引用,该数据库包含用户信息,包括用户是否正确登录的事实

我想回顾一下我的解决方案的安全性,并开始研究我应该如何在登录时设置cookies,在服务器端存储的会话中存储什么,以及如何在注销时销毁这些信息,因为到目前为止,我的用户登录已久,这不是我的意图

我的问题是如何在Flask中正确处理整个用户登录/会话/注销问题没有明确的答案-一些人在谈论使用Flask的响应。删除\u cookie()函数,其他人使用将其过期。将\u cookie()设置为零过期时间,其他人提到Flask的会话模块,其他危险的模块

对于应与Flask、代码示例等一起使用的模块,最安全、最正确和最恰当的处理方式是什么?

背景 方法#1 处理会话的一种简单而安全的方法是执行以下操作:

  • 使用包含会话ID(随机数)的会话cookie
  • 使用密钥对会话cookie进行签名(以防止回火-这就是它的作用)
  • 将实际会话数据存储在服务器端的数据库中(按ID索引,或使用NoSQL键/值存储)
  • 当用户访问您的页面时,您从数据库读取数据
  • 当用户注销时,您将从数据库中删除数据
请注意,有一些缺点

  • 您需要维护该数据库后端(更多维护)
  • 您需要针对每个请求访问数据库(性能较低)
方法#2 另一种选择是将所有数据存储在cookie中,并对所述cookie进行签名(可选地进行加密)。然而,这种方法也有许多缺点:

  • 这在后端更容易(维护更少,性能更好)
  • 您需要小心不要包含用户在会话中不应看到的数据(除非您正在加密)
  • 可以保存在cookie中的数据量是有限的
  • 您不能使单个会话无效(!)
代码 实际上,它实现了方法2

要从#2变为#1,您所要做的就是:

  • 生成随机会话ID(您可以使用
    os.uradom
    +
    base64
  • 将会话数据保存在数据库后端,按会话ID进行索引(使用JSON等序列化,如果需要Python对象,请选择Picke,如果可以,请避免)
  • 当用户注销时,从数据库后端删除会话
确保您受到会话固定攻击的保护。为此,请确保在用户登录时生成新的会话ID,并且不要重用其现有会话ID

另外,确保在会话上实现过期(只需添加“最后一次看到”的时间戳)


您很可能会这样做。

我建议您使用simplekv模块的会话插件来持久化会话信息

从概念上讲,Flask KVSession使用Flask会话接口为上述方法#1提供了一个实现。这样,您就不必修改代码以使其运行,并且可以使用扩展方法来执行其他操作,例如会话过期。它还负责会话签名,并进行一些基本检查以防止篡改。不过,您仍然希望通过HTTPS执行此操作,以绝对防止会话窃取

Simplekv是处理各种数据存储格式的写入和读取的实际模块。这可以像平面文件一样简单,可以像Redis一样快,也可以像数据库一样持久(NoSQL或其他)。这是一个单独模块的原因是,Flask KVSession可以只是Flask的普通适配器,而无需了解存储机制

您可以在上找到代码示例。如果你需要更多的例子,我可以提供一个

或者,如果您需要一个更企业化、更重量级的Flask服务器端实现,您也可以使用Bicker作为WSGI中间件来研究这个方法(这意味着其他框架也使用它)。烧杯API为

与Flask KVSession相比,Bicker提供的一个优势是,Bicker将延迟加载会话,因此如果您不读取会话信息,它就不会在每次调用时连接到数据库。然而,烧杯依赖于SQLAlchemy,它将是一个比simplekv模块更大的模块


除非那个特定的性能案例很重要,否则我仍然会选择Flask KVSession,因为它的API稍微简单一些,代码库也更小

我知道这两种方法的优缺点,我更愿意使用第一种方法,但是,我的问题主要是关于代码示例和模块建议,考虑到所需的方法、最新的Flask版本(我读过的将处理cookie从Werkzeug更改为其他版本)等等。。。想编写一个代码示例吗?@SpankMe我恐怕现在没有时间编写代码示例。尽管如此,我还是为您添加了所需的步骤和要点。这仍然不能解决我提到的关于使用Flask会话模块与它的危险性、注销时删除cookie等问题的疑问。@SpankMe Flask使用它的危险性。只要你删除(或清除)后端的会话,删除cookie是没有用的。@SpankMe因为在网络不可用时删除cookie而不是后端数据就等于问你的前男友/女朋友:“对不起,我现在不能换我家的锁,你介意把钥匙扔掉吗?”。如果他们想对你做坏事,他们不会扔垃圾