【问题标题】:When is the ring anti-forgery token inserted?什么时候插入戒指防伪令牌?
【发布时间】:2017-04-07 18:48:48
【问题描述】:

我试图了解环形防伪令牌何时生成或插入 HTML 页面。我正在使用 Compojure / ring / hiccup,但我认为我的问题实际上是关于 ring 的。我本身没有任何问题:我只想知道何时以及如何“注入”防伪令牌。

ring.util.anti-forgery 中的 anti-forgery-field 函数是这样实现的:

(html (hidden-field "__anti-forgery-token" *anti-forgery-token*)

如果我在 REPL 中调用此函数,我会得到:

REPL>  (println (anti-forgery-field))
<input id="__anti-forgery-token" name="__anti-forgery-token" type="hidden" value="Unbound: #&apos;ring.middleware.anti-forgery/*anti-forgery-token*" />

仍然在 REPL,如果我尝试获取这个 var,我会得到相同的“未绑定”变量:

> ring.middleware.anti-forgery/*anti-forgery-token*
=> #object[clojure.lang.Var$Unbound 0x1eae055 "Unbound: #'ring.middleware.anti-forgery/*anti-forgery-token*"]

我不明白“未绑定”值是什么,也不明白它何时被转换(通过环?)为交付的实际令牌。而且我特别不明白连接到网站的几个用户是如何获得不同的令牌(每个会话)的。

那个变量总是“未绑定”的吗?它何时/如何成为“绑定”(如果确实如此?)?

另外,如果我有环会话 ID(比如 "ring-session=310678be-9ef6-41a7-a12a-b2417de4a79f"),我如何在 Clojure REPL (在服务器端),对应的防伪令牌的值?

【问题讨论】:

  • 尝试阅读github.com/ring-clojure/ring-anti-forgery/blob/master/src/ring/… 的源代码,这并没有做任何特别花哨的事情。完成此操作后,如果您对机制有具体问题,这可能是一个很好的问题。
  • @amalloy:嗯,我已经读过了,我只是不明白。这可能不是因为我不仅不了解 ring 也不了解 Clojure(这可以解释为什么使用源代码对我没有帮助以及为什么我问这个问题)。我认为一个问题的答案可以帮助我理解该机制是:“当两个用户登录我的网站并且我知道他们的环会话 ID 时,我如何从 REPL 读取两个不同的防伪令牌?”。这真的会帮助我了解幕后发生的事情。

标签: clojure csrf-protection ring


【解决方案1】:

它仅在单个请求的上下文(动态环境,当前堆栈,如果你愿意的话)中绑定。将其视为线程局部变量/绑定。从 REPL 查看应用程序状态时,您不在请求的上下文中。

必须是这种方式,因为它必须为每个用户提供不同的值。如果您在不允许对动态环境进行这种控制的环境中工作,则可以通过显式查找调用来模拟类似的行为。

在请求期间在中间件中建立对正确会话值的绑定,目前在这里:

https://github.com/weavejester/ring-anti-forgery/blob/master/src/ring/middleware/anti_forgery.clj#L67

(binding [*anti-forgery-token* (session-token request)]
  ;; ...
  )

【讨论】:

  • 哦,这对我来说是全新的。感谢您的解释:现在感觉不那么神秘了,我明白为什么我一直认为这是 REPL 中的“未绑定”。
  • 有什么方法可以将 REPL 连接到特定的(本地开发)会话以检查和修改其动态变量?还是由于上述原因,这是一个失败的原因?
  • 您可以创建一个小测试函数来接受请求(即测试处理程序)并将其包装在中间件中。
猜你喜欢
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
  • 2013-03-31
  • 2019-03-05
  • 2018-01-16
  • 2013-11-27
相关资源
最近更新 更多