gpt4 book ai didi

clojure - 如何在特定的reitit路由上应用环防伪?

转载 作者:行者123 更新时间:2023-12-02 18:45:57 24 4
gpt4 key购买 nike

在包装使用 metosin/reitit 创建的特定路由时,我不断收到“无效的防伪 token ”消息reitit.ring/ring-router 。我也尝试过 reitit 的 middleware registry ,但它也不起作用。尽管我可以使用 wrap-sessionwrap-anti-forgery 包装整个处理程序,但这会破坏 reitit 在允许特定于路由的中间件方面的优势。

(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}))

最佳答案

事实证明metosin/reitit为每条路由创建一个 session 存储(有关更多信息,请参阅issue 205);换句话说,ring-anti-forgery 不起作用,因为 reitit 不为每个路由使用相同的 session 存储。

截至本回答之时,维护者建议如下(从问题中复制,以便于在 Stack Overflow 中引用):

  1. 将封装 session 挂载在路由器之外,这样整个应用程序就只有一个 mw 实例。在环处理程序中有一个 :middleware 选项:
(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]}))
  • 创建单个 session 存储并在路由表中使用它( session 中间件的所有实例将共享单个存储)。
  • (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]])))

    此答案中未显示维护者要求 PR 的第三个选项。

    关于clojure - 如何在特定的reitit路由上应用环防伪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53022184/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com