2

我希望从辅助窗口登录到基于 django 的网站。即我有一个连接到 django 服务器的 flash 文件。在 Flash 文件中选择登录时,它会打开另一个窗口(即 Facebook 登录弹出窗口)。基于Facebook客户端的登录流程用于登录用户,并将从中获取的user_id发送到django服务器进行识别和登录。我在服务器上验证了现阶段django.contrib.auth的身份验证和登录功能被调用并且 user.is_authenticated() 返回 True。

但是在包含 Flash 文件的原始窗口中的客户端,用户有时仍然是 AnonymouseUser,即未登录。在其他时候,用户被正确识别。

在检查当前会话的数据库条目时,我看到当用户没有登录时,存在两个会话,而当用户登录时只有一个会话。

我不确定为什么会创建一个额外的会话以及如何解决这个问题。

注意 - 我正在使用自定义身份验证后端。

更新 我深入研究了 django 系统,看看发生了什么。Django 有一种机制可以在维护数据的同时更改会话的密钥。在我的情况下发生的是会话密钥的更改发生了两次。一旦在登录过程中按预期发生。但紧随其后,另一个请求会导致会话密钥发生变化。这个请求不是我在我的客户端代码中提出的。似乎请求是针对 /favicon.ico 不确定这是从哪里来的。任何帮助表示赞赏。

更新 2 它似乎与 favicon.ico 有关 现在我在根目录下服务它,在几次刷新后一切正常。我认为问题发生在之前,因为浏览器对 favicon 的请求在会话失败时弄乱了会话。在确认并关闭此问题之前,我将进行更多测试。

更新 3 未解决。如果有人能指出我正确的方向,我将不胜感激。在那之前,我会看看是否可以更改登录流程以绕过此机制。

更新 4 所以在经历了一些堆栈跟踪(如果需要我可以分享)之后,我意识到了以下几点。由于 Django 在登录用户时更改了会话 ID,因此它会创建一个会话 ID 产生两个会话 ID 的情况,如下所示。请求 1 - 导致登录的 ajax 请求。此请求具有 django 先前提供的会话密钥,例如 key1。作为响应,服务器发回一个新的会话密钥,比如 key2,同时从其内存中删除 key1(在我的情况下是数据库)请求 2 - 这是浏览器在请求 1 之后对 favicon.ico 发出的隐式请求。(您可能知道这个请求是由浏览器发出的,我无法控制它)这个请求还带有 sam 原始密钥,即 key1。由于这个键在 Django 的内存中不可用,它创建一个新键 key3 并在响应中发回。

结果,所有进一步的请求都是用 key3 发出的,django 用一个新的会话来识别它,并且用 key2 存储的登录状态会丢失。

我不确定这是否是 Django 中的错误,或者这是预期的行为。但是,如果这是一种预期的行为,那么当任何客户端在等待先前的响应之前发出多个 ajax 请求并触发键更改时,它将产生问题。

话虽如此,我最初的问题仍然存在,如果找到解决方案,我将发布解决方案。

4

1 回答 1

0

我现在申请的解决方案是对登录 url 进行多次调用,截至目前 2 次。这意味着如果事情在更新 4 中按上述说明进行,则第二个登录请求将使用 key3 并接收 key4。但是由于我的代码或浏览器没有其他并发请求,因此该密钥将保留并且用户将始终登录。经过 2 天的测试,到目前为止似乎工作正常。

但是我的解决方案是一种解决方法,我仍然想知道这是 django 中的错误还是我的代码逻辑有问题。

于 2012-11-12T13:10:25.717 回答