Как применить кольцевую анти-подделку на определенных маршрутах? - PullRequest
0 голосов
/ 27 октября 2018

Я получаю «Недопустимый токен подделки» при переносе определенных маршрутов, созданных с помощью метосин / рейтит reitit.ring/ring-router.Я также пробовал реестр промежуточного программного обеспечения reitit , но он тоже не работал.Хотя я мог бы просто обернуть весь обработчик с wrap-session и wrap-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}))

1 Ответ

0 голосов
/ 19 января 2019

Оказывается, что metosin / reitit создает одно хранилище сеансов для каждого маршрута (для получения дополнительной информации обратитесь к Issue 205 ); другими словами, защита от подделки звонков не работает, потому что reitit не использует одно и то же хранилище сеансов для каждого маршрута.

На момент получения ответа сопровождающий предлагает следующее (скопировано из вопроса для удобства ссылок в переполнении стека):

  1. смонтировать wrap-сессию вне маршрутизатора, чтобы для всего приложения был только один экземпляр mw. Для этого есть опция промежуточного программного обеспечения в обработчике кольца:
(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. создайте одно хранилище сеансов и используйте его в таблице маршрутизации (все экземпляры промежуточного программного обеспечения сеансов будут совместно использовать одно хранилище).
(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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...