Django 以编程方式设置 Django 会话 cookie
Django set django session cookies programmatically
我正在使用 django 创建一个 saas,软件即服务站点。
由于项目要求,用户在 schemas/tenants 中,为此我使用了很棒的 django-tenant-schemas 应用程序,一个用户可以在不同的模式中拥有帐户(他们共享用户名和密码).. .我想让用户或多或少自由地浏览他们所处的不同模式...为此我创建了一个视图,用户可以在其中 select 了解他想要使用的模式。
当我使用应用程序范围的 cookie 会话时,即当我将 cookie 设置为“.domain.ext”(django documentation)时,它工作正常,但它不是我们真正想要的行为申请。
我们真正需要的是能够在不同的浏览器选项卡上拥有不同版本的应用程序。
所以我们必须将 cookie 配置设置为 "domain.ext",然后一切都会中断,因为原始视图在一个租户上,而下一个视图(刚刚登录的用户真正所属的地方)在另一个租户内,然后旧 cookie 已删除。
所以问题是我如何以编程方式在新视图上正确设置 cookie,以便真正属于该 tenat 的用户仍然经过身份验证。
或者我们可以使用任何替代方法吗?有例子吗?
根据要求编辑澄清:
A 属于 2 个模式 SH1 和 SH2,他拥有相同的用户名和密码。
在每次更改密码时,密码哈希都会复制到它们所属的所有模式中,因此它们不必记住特定的密码或用户名。
当此人登录 SH1 时,url 将是 sh1.domain.com 当他登录 SH2 时,url 将是 sh2.domain.com
所以假设此人现在登录到模式 SH1,他决定切换到模式 SH2,为了能够做到这一点,我需要用户仍然经过身份验证,以便视图必须在 SH1 模式上,但随后它被重定向到新模式强制对用户进行身份验证但是由于当用户登陆下一个 url sh1.domain.com/whatever 时 cookie 被设置为特定于域(默认的 django 行为)之前的 cookie 被删除,因此他必须重新登录才能访问。
如果我理解正确,您希望能够具有跨域 cookie 的 行为 ,但实际上 使用 跨域 cookie。
第一个想到的答案是"well, use a cross-domain cookie"。这几乎是您想要使用跨域 cookie 的情况的普通示例。设计一个复杂的解决方案,这样你就可以避免使用简单的解决方案永远不会有好结果 :-) 除非还有一些你没有透露的其他限制在起作用,否则我首先会质疑你是否不应该简单地做这个方式。
但是,假设 是 一个很好的理由(坦率地说,我很想知道那是什么),您将要面对的问题是浏览器安全本质上是试图阻止您完全按照您的建议行事。您想从域 SH2 知道在域 SH1 上设置的 cookie 是否发生了某些事情。这正是 cookie 安全策略旨在防止的情况。
解决此问题的唯一方法是拥有可以共享知识的第三方。当用户 A 登录到 SH1 时,您像往常一样进行密码验证 - 但您还在某处 post 一个标志,上面写着 "User A is now on SH1"。当 A 登录到 SH2 时,你 post 相应的标志。如果 A 返回到 SH1,您检查中央真实来源,发现他们当前在 SH2 上,并强制登录。
您可能可以通过操纵 cookie 和会话密钥来做到这一点,但我怀疑更简单的方法是使用 Authentication backend。您将要编写的是一个与 Django 自己的后端非常相似的身份验证后端 - 除了它将根据中央真实来源检查跨域登录状态。
如何实现 "source of truth" 取决于您 - 内存缓存、数据库 table 或任何其他数据源都可以。关键的想法是你不是试图重写 cookie 以便相同的 cookie 在每个站点上工作——你保持每个站点的 cookie 独立,而是使用 Django 的身份验证基础结构来保持 cookie 在用户在域之间移动时同步。
我正在使用 django 创建一个 saas,软件即服务站点。
由于项目要求,用户在 schemas/tenants 中,为此我使用了很棒的 django-tenant-schemas 应用程序,一个用户可以在不同的模式中拥有帐户(他们共享用户名和密码).. .我想让用户或多或少自由地浏览他们所处的不同模式...为此我创建了一个视图,用户可以在其中 select 了解他想要使用的模式。
当我使用应用程序范围的 cookie 会话时,即当我将 cookie 设置为“.domain.ext”(django documentation)时,它工作正常,但它不是我们真正想要的行为申请。
我们真正需要的是能够在不同的浏览器选项卡上拥有不同版本的应用程序。
所以我们必须将 cookie 配置设置为 "domain.ext",然后一切都会中断,因为原始视图在一个租户上,而下一个视图(刚刚登录的用户真正所属的地方)在另一个租户内,然后旧 cookie 已删除。
所以问题是我如何以编程方式在新视图上正确设置 cookie,以便真正属于该 tenat 的用户仍然经过身份验证。
或者我们可以使用任何替代方法吗?有例子吗?
根据要求编辑澄清:
A 属于 2 个模式 SH1 和 SH2,他拥有相同的用户名和密码。 在每次更改密码时,密码哈希都会复制到它们所属的所有模式中,因此它们不必记住特定的密码或用户名。
当此人登录 SH1 时,url 将是 sh1.domain.com 当他登录 SH2 时,url 将是 sh2.domain.com
所以假设此人现在登录到模式 SH1,他决定切换到模式 SH2,为了能够做到这一点,我需要用户仍然经过身份验证,以便视图必须在 SH1 模式上,但随后它被重定向到新模式强制对用户进行身份验证但是由于当用户登陆下一个 url sh1.domain.com/whatever 时 cookie 被设置为特定于域(默认的 django 行为)之前的 cookie 被删除,因此他必须重新登录才能访问。
如果我理解正确,您希望能够具有跨域 cookie 的 行为 ,但实际上 使用 跨域 cookie。
第一个想到的答案是"well, use a cross-domain cookie"。这几乎是您想要使用跨域 cookie 的情况的普通示例。设计一个复杂的解决方案,这样你就可以避免使用简单的解决方案永远不会有好结果 :-) 除非还有一些你没有透露的其他限制在起作用,否则我首先会质疑你是否不应该简单地做这个方式。
但是,假设 是 一个很好的理由(坦率地说,我很想知道那是什么),您将要面对的问题是浏览器安全本质上是试图阻止您完全按照您的建议行事。您想从域 SH2 知道在域 SH1 上设置的 cookie 是否发生了某些事情。这正是 cookie 安全策略旨在防止的情况。
解决此问题的唯一方法是拥有可以共享知识的第三方。当用户 A 登录到 SH1 时,您像往常一样进行密码验证 - 但您还在某处 post 一个标志,上面写着 "User A is now on SH1"。当 A 登录到 SH2 时,你 post 相应的标志。如果 A 返回到 SH1,您检查中央真实来源,发现他们当前在 SH2 上,并强制登录。
您可能可以通过操纵 cookie 和会话密钥来做到这一点,但我怀疑更简单的方法是使用 Authentication backend。您将要编写的是一个与 Django 自己的后端非常相似的身份验证后端 - 除了它将根据中央真实来源检查跨域登录状态。
如何实现 "source of truth" 取决于您 - 内存缓存、数据库 table 或任何其他数据源都可以。关键的想法是你不是试图重写 cookie 以便相同的 cookie 在每个站点上工作——你保持每个站点的 cookie 独立,而是使用 Django 的身份验证基础结构来保持 cookie 在用户在域之间移动时同步。