我正在使用自定义session / auth / users / acl系统在Django上编写论坛应用程序。其中一个目标是允许用户浏览和使用我的应用程序,即使他们已关闭cookie。来自PHP世界,问题的最佳解决方案是将sid =附加到页面上的每个链接。我打算如何做到这一点:
会话中间件检查用户是否有会话cookie或记住我的cookie。如果他这样做,这很可能意味着cookies适合他。如果他没有,我们生成新的会话ID,打开新的会话(在DB中的会话表中创建新条目),然后发送cookie并将用户重定向到他所在的位置,但是将SID附加到url。重定向中间件后,将查看是否可以从cookie或GET获取会话ID。如果它的cookie,我们停止向URL添加sid。如果它的GET,我们保留它们。
我打算通过使用我自己的函数装饰django.core.urlresolvers.reverse和reverse_lazy来将SID = part插入到url中,并将sid =附加到它们。然而,这引发了一些问题,因为两个中间件都是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添加到正则表达式省略的位置。
哪种方法更好?当前一个线程也安全吗?
答案 0 :(得分:1)
首先:在URL中使用SID是非常危险的,例如,如果您为他登录的朋友复制并粘贴链接。由于大多数用户不知道SID是什么,他们会遇到这个问题。因此,你永远不应该在网址中使用SID,因为Facebook和朋友都需要cookie,你也应该没事......
考虑到这一点,monkeypatching urlresolvers.reverse幸运地不起作用!可以使用自定义URLResolvers子类,但我建议不要使用它。
是的,您的中间件不是线程安全的。中间件只初始化一次并在线程之间共享,这意味着在self上存储任何东西都是而不是线程安全。