访问Django中视图之外的会话/请求信息

Cpp*_*ner 4 django

我需要存储一些来自某些非django应用程序的特殊cookie.我可以在视图中这样做

request.session[special_cookies'] = special_cookies
Run Code Online (Sandbox Code Playgroud)

但是在非视图py文件中,我需要访问这个特殊的cookie.

根据文档,我可以做到这一点

>>> from django.contrib.sessions.backends.db import SessionStore
>>> import datetime
>>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
>>> s['last_login'] = datetime.datetime(2005, 8, 20, 13, 35, 10)
>>> s['last_login']
datetime.datetime(2005, 8, 20, 13, 35, 0)
>>> s.save()
Run Code Online (Sandbox Code Playgroud)

如果我不提供会话密钥,Django将为我生成一个.我担心获得许多新会话密钥的效果.(当你有多个用户时我不认为这很好,对吧......?)

我希望用户将这个特殊的cookie绑定到用户的会话中.但是,出于安全原因,我不想将其保存在用户配置文件中.我们登录时会生成此cookie(我们的应用程序将发送此特殊cookie).我们希望在整个浏览会话中来回发送此cookie.

我该如何解决这个问题?

非常感谢你!


#views.py
request.session['special_cookies'] = library.get_special(user, pwd)

#library.py
def get_special_cookies(user, pwd):
   res = get_special_cookies("http://foobar.com/api/get_special_cookies", user, pwd)

#foobar.py  (also non-views)
def do_this(user, special_cookies)
Run Code Online (Sandbox Code Playgroud)

我很确定这很好......

#views_2.py
def dummy_views(request):
    foobar.do_this(request.user, request.session['special_cookies'])
Run Code Online (Sandbox Code Playgroud)

但有些情况下,我不希望通过视图/调用get_sepcial_cookies获取我的特殊cookie.我希望它能持续下去.或者我是否在思考..?

Pau*_*ine 6

为了解释你为什么处于危险的道路,我们必须记住为什么首先发明的服务器端会话:

HTTP是无状态协议.无状态协议不要求服务器在多个请求期间保留关于每个用户的信息或状态.例如,当需要Web服务器为用户定制网页的内容时,Web应用程序可能必须跟踪用户在页面之间的进度.常见的解决方案是使用HTTP cookie.其他方法包括服务器端会话,隐藏变量(当前页面包含表单时)和使用URI编码参数的URL重写.

Django是一个非常成熟的框架; 如果在Django中似乎很难实现某些目标,那么你可能会采取错误的方法解决问题.即使你可以直接在会话后端存储服务器端会话信息,对我来说这似乎是糟糕的设计,因为会话数据与请求之外的相关性不大.

恕我直言,如果你需要在应用程序之间共享身份验证/授权数据,你应该考虑像OAuth这样的东西,否则你最终会得到一些不安全,脆弱,丑陋和难以支持的东西.

(对不起,如果我听起来居高临下,英语不是我的本土成语).

[更新]

嗨保罗.非常感谢你.我相信我的团队不想引入OAuth或任何形式的额外层次的认证机制.但是你不反对在HttpResponse.COOKIES中插入这个特殊的cookie吗?

如果您真的想要这样做,请说几句:

  • 您将受到"相同域"限制(另一个应用程序应位于同一TLD中)的约束
  • 你应该使用某种签名来避免篡改cookie

这是一个比request.session更好的解决方案吗?

有一些机制可以在更高层次上处理这类问题.例如:

  • 如果要根据某些cookie的值在每个模板上下文中生成变量,可以编写自定义上下文处理器.
  • 如果要根据cookie的存在重新路由视图,则应编写自定义中间件.

如果没有关于您的目标的更多详细信息,我无法提供更具体的解决方案,但是使用这些钩子可以避免重复代码在每个视图中测试外部cookie - 请注意,有关cookie的所有内容都与请求/响应上下文相关联在它之外毫无意义.