2

我正在使用自定义 session/auth/users/acl 系统在 Django 上编写论坛应用程序。目标之一是允许用户浏览和使用我的应用程序,即使他们关闭了 cookie。来自 PHP 世界,问题的最佳解决方案是将 sid= 附加到页面上的每个链接。这是我打算如何做的:

会话中间件检查用户是否有会话 cookie 或记住我的 cookie。如果他这样做了,这很可能意味着 cookie 对他有用。如果他没有,我们生成新的会话 ID,打开新会话(在数据库的会话表中创建新条目),然后发送 cookie 并将用户重定向到他所在的位置,但 SID 附加到 url。重定向中间件后将查看是否可以从 cookie 或 GET 获取会话 ID。如果它的 cookie,我们停止将 sid 添加到 url。如果是 GET,我们会保留它们。

我计划通过使用我自己的附加 ?sid= 的函数装饰 django.core.urlresolvers.reverse 和 reverse_lazy 将 SID= 部分插入 url。然而,这引发了一些问题,因为这两个中间件 urlresolvers 都不是线程安全的。为了克服这个问题,我创建了这样的东西:

class SessionMiddleware(object):
    using_decorator = False
    original_reverse = None

    def process_request(self, request):        
        self.using_decorator = True
        self.original_reverse = urlresolvers.reverse
        urlresolvers.reverse = session_url_decorator(urlresolvers.reverse, 's87add8ash7d6asdgas7dasdfsadas')

    def process_response(self, request, response):
        # Turn off decorator if we are using it
        if self.using_decorator:
            urlresolvers.reverse = self.original_reverse
            self.using_decorator = False
        return response

如果 SID 必须通过链接传递,则 process_request 将 using_decorator 设置为 true 并将未修饰的 urlresolvers.revers 存储在单独的方法中。页面呈现后 process_response 检查 using_decorator 以查看它是否必须执行“垃圾收集”。如果是,它会将反向函数返回到原始未修饰状态。

我的问题是,这种方法是线程安全的吗?或者我的论坛流量增加可能会导致中间件一次又一次地装饰这些功能,无法运行“垃圾收集”?我还坚持使用正则表达式来简单地浏览生成的链接的 HTML 响应,并提供模板过滤器和变量以手动将 SID 添加到正则表达式省略的位置。

哪种方法更好?当前的一个线程也安全吗?

4

1 回答 1

1

首先:在 URL 中使用 SID 是非常危险的,例如,如果您复制并粘贴一个以您身份登录的朋友的链接。由于大多数用户不知道 SID 是什么,他们会遇到这个问题。因此,您永远不应该在 url 中使用 SID,因为 Facebook 和朋友都需要 cookie,所以您也应该没问题...

考虑到这一点,幸运的是,monkeypatching urlresolvers.reverse 不起作用!使用自定义 URLResolvers 子类可能可行,但我建议不要这样做。

是的,您的中间件不是线程安全的。中间件只初始化一次并在线程之间共享,这意味着在 self 上存储任何东西都不是线程安全的。

于 2012-05-29T08:18:31.453 回答