环形防伪中间件是否可以有条件地应用?

Can the ring-anti-forgery middleware be applied conditionally?

我们有一个使用 HttpKit 来处理请求的 Web 应用程序和一个用 Ring 中间件包装的处理程序。

处理程序类似于:

(def handler
  (->  #'req-handler
    (wrap-defaults site-defaults)
    (wrap-content-type-and-encoding)
    (wrap-cookies)
    (wrap-stacktrace)))

在站点默认值中可以找到:

 :security  { ...
              :anti-forgery         anti-forgery-setting
              ... }

应用程序过去只处理来自浏览器的请求,但现在一些端点响应 API 请求,包括 POST 操作。

在我可以阅读的文档中:

This middleware will prevent all HTTP methods except for GET and HEAD from accessing your handler without a valid anti-forgery token.

You should therefore only apply this middleware to the parts of your application designed to be accessed through a web browser. This middleware should not be applied to handlers that define web services.

有没有办法有条件地应用防伪设置,或者根据要求提供不同版本的site-defaults

您可以使用 ring.middleware.conditional's operators to conditionally add middleware. For example, to conditionally add the api-defaults mentioned in the :


(require '[ring.middleware.conditional :as middleware.conditional]
(require '[ring.middleware.defaults :refer [api-defaults site-defaults])

(defn wrap-api-defaults [handler]
  (wrap-defaults handler api-defaults))

(defn wrap-site-defaults [handler]
  (wrap-defaults handler site-defaults))

(def handler
  (-> #'req-handler
      (middleware.conditional/if-url-starts-with "/api" wrap-api-defaults)
      (middleware.conditional/if-url-doesnt-start-with "/api" wrap-site-defaults)
      (wrap-content-type-and-encoding)
      (wrap-cookies)
      (wrap-stacktrace)))