首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在特定路线上应用防伪?

如何在特定路线上应用防伪?
EN

Stack Overflow用户
提问于 2018-10-27 13:08:30
回答 1查看 751关注 0票数 6

在包装用metosin/reitit reitit.ring/ring-router创建的特定路由时,我一直得到“无效的防伪令牌”。我也尝试过reitit的中间件注册表,但它也不起作用。虽然我只需要用wrap-sessionwrap-anti-forgery包装整个处理程序,但这就违背了reitit在允许特定于路由的中间件方面的优势。

代码语言:javascript
复制
(ns t.core

 (:require [immutant.web :as web]
           [reitit.ring :as ring]
           [ring.middleware.anti-forgery :refer [wrap-anti-forgery]]
           [ring.middleware.content-type :refer [wrap-content-type]]
           [ring.middleware.params :refer [wrap-params]]
           [ring.middleware.keyword-params :refer [wrap-keyword-params]]
           [ring.middleware.session :refer [wrap-session]]
           [ring.util.anti-forgery :refer [anti-forgery-field]]
           [ring.util.response :as res]))


(defn render-index [_req]
 (res/response (str "<form action='/sign-in' method='post'>"
                    (anti-forgery-field)
                    "<button>Sign In</button></form>")))

(defn sign-in [{:keys [params session]}]
 (println "params: " params
          "session:" session)
 (res/redirect "/index.html"))

(defn wrap-af [handler]
 (-> handler
     wrap-anti-forgery
     wrap-session
     wrap-keyword-params
     wrap-params))

(def app
 (ring/ring-handler
  (ring/router [["/index.html" {:get render-index
                                :middleware [[wrap-content-type]
                                             [wrap-af]]}]
                ["/sign-in"    {:post sign-in
                                :middleware [wrap-af]}]])))

(defn -main [& args]
 (web/run app {:host "localhost" :port 7777}))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-19 08:56:56

事实证明,metosin/reitit为每个路由创建了一个会话存储(更多信息请参考第205期 );换句话说,由于reitit不对每个路由使用相同的会话存储,所以环防伪造无法工作。

在回答此问题时,维护人员建议如下(为便于在堆栈溢出中引用而从问题中复制):

  1. 挂载路由器之外的包会话,所以整个应用程序只有一个mw实例。在循环处理程序中有:中间件选项:
代码语言:javascript
复制
(require '[reitit.ring :as ring])
(require '[ring.middleware.session :as session])

(defn handler [{session :session}]
  (let [counter (inc (:counter session 0))]
    {:status 200
     :body {:counter counter}
     :session {:counter counter}}))

(def app
  (ring/ring-handler
    (ring/router
      ["/api"
       ["/ping" handler]
       ["/pong" handler]])
    (ring/create-default-handler)
    ;; the middleware on ring-handler runs before routing
    {:middleware [session/wrap-session]}))
  1. 创建单个会话存储并在路由表中使用它(会话中间件的所有实例都将共享单个存储)。
代码语言:javascript
复制
(require '[ring.middleware.session.memory :as memory])

;; single instance
(def store (memory/memory-store))

;; inside, with shared store
(def app
  (ring/ring-handler
    (ring/router
      ["/api"
       {:middleware [[session/wrap-session {:store store}]]}
       ["/ping" handler]
       ["/pong" handler]])))

在这个答案中没有显示的是维护人员要求进行公关的第三个选项。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53022184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档