2 回答
TA贡献1804条经验 获得超2个赞
作为提出另一个问题的人:
gorilla/context 允许您在请求中存储数据。如果您有一些中间件在决定继续之前对请求进行一些预处理(即反 CSRF),您可能希望在请求中存储一个令牌,以便您的处理程序可以将其传递给模板。该大猩猩/背景文档解释得好:
...路由器可以设置从 URL 中提取的变量,以后的应用程序处理程序可以访问这些值,或者它可以用于存储会话值以在请求结束时保存。还有其他几种常见用途。
您可能还需要在会话数据存储:错误消息从表单提交,用户ID,或者“规范”令牌为游客可能会被存储在这里的CSRF的版本。如果您尝试在请求上下文中存储错误消息,然后重定向用户,您将丢失它(这是一个新请求)。
那么为什么要在会话上使用上下文呢?它更轻巧,并允许您将应用程序的各个部分(通常是 HTTP 中间件!)彼此分离。
例子:
请求进来
CSRF 中间件检查会话中是否存在现有的 CSRF 令牌。不存在,所以设置一个。
它还将此新令牌(通过请求上下文!)传递给呈现表单的处理程序,以便它可以在模板中呈现它(否则您将不得不再次从会话中提取令牌,这是白费力气)
请求完成。
表单提交的新请求
该令牌仍保留在会话中,因此我们可以将其与表单中提交的令牌进行比较。
如果检查出来,我们继续处理表格
如果没有,我们可以在会话中保存一个错误(一条闪现消息;即读取后删除的消息)并重新定向。
这个重定向是一个新的请求,因此我们不能通过这里的请求上下文传递错误消息。
TA贡献1847条经验 获得超7个赞
一个例子。
我正在编写这个多社区论坛软件。现在我有一个为主域提供不同内容的 gorilla/mux 路由器和另一个为 subdomain.domain.tld 过滤的不同内容提供服务的路由器。
上下文在这里非常有用,否则你会一遍又一遍地重复自己。因此,如果我知道对于子域路由器,每个请求都会执行字符串操作以找出子域名并检查它是否存在于数据库中,我可以在此处(在上下文中)为每个请求执行此操作,然后将子域名存储在上下文变量。同样,如果将论坛的类别 slug 或论坛 slug 或线程 slug 设置为将其传递给处理程序,请将需要在“上下文”中完成的处理保留在处理程序中并减少代码。
所以上下文的优势本质上是保持代码干燥。
就像 elihrar 写的那样,他的 CSRF 令牌示例。如果您知道需要在每个请求上检查 CSRF 令牌 - 不要在需要执行此操作的每个处理程序中重复此检查,而是编写上下文包装器 (/http.Handler) 并为每个请求执行此操作。
- 2 回答
- 0 关注
- 258 浏览
添加回答
举报