Подтвердить что ты не робот

Не удалось выполнить запрос POST в Clojure

Недавно я начал изучать Clojure, и я хотел создать простое веб-приложение с базовыми функциями CRUD. Здесь я нашел хороший учебник: http://www.xuan-wu.com/2013-09-21-Basic-Web-Application-in-Clojure.

Запросы GET работают нормально, но всякий раз, когда я пытаюсь отправить запрос, я получаю следующую ошибку:

Invalid anti-forgery token

В учебнике, о котором я упоминал ранее, не говорится ни о какой безопасности. Я немного искал, и кажется, что мне не хватает какого-то компонента Compojure, который должен генерировать токен для создания запросов POST. В некоторых местах упоминалось, что я должен был произойти автоматически без каких-либо изменений с моей стороны. Я все еще не уверен, что это такое, чего я не хватает. Вот мой код:

(ns myblog.handler
    (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [myblog.views :as views]
            [myblog.posts :as posts]
            [ring.util.response :as resp]
            [ring.middleware.basic-authentication :refer :all]))

(defn authenticated? [name pass]
  (and (= name "user")
       (= pass "pass")))

(defroutes public-routes
    (GET "/" [] (views/main-page))
    (route/resources "/"))

(defroutes protected-routes
    (GET "/admin" [] (views/admin-page))
    (GET "/admin/add" [] (views/add-post))
    (POST "/admin/create" [& params]
        (do (posts/create params)
            (resp/redirect "/admin"))))

(defroutes app-routes
    public-routes
    (wrap-basic-authentication protected-routes authenticated?)
    (route/not-found "Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))

Опять же, только запрос POST "/admin/create" терпит неудачу с неверной ошибкой маркера. Любая идея, что я делаю неправильно?

4b9b3361

Ответ 1

Ваша проблема связана с настройками по умолчанию - по умолчанию и по умолчанию. Конфигурация по умолчанию по умолчанию по умолчанию добавляет антивирусную защиту CSRF и любой почтовый запрос, который не включает действительный CSRF-токен, будет заблокирован.

Есть несколько способов обойти это.

  • Используйте api-defaults вместо настроек по умолчанию. Конфигурация по умолчанию api-defaults предназначена для сайтов, на которых вы обслуживаете веб-API, и включает в себя защиту CSRF, включенную в параметры по умолчанию для сайта, которая предназначена для более традиционного веб-сайта, где почтовые запросы создаются по форме, которая была ранее доставлена через запрос на получение и включает в себя csrf-токен как скрытое поле. Недостатком этого решения является то, что он может также отключить другое промежуточное программное обеспечение, которое вы хотите включить.

  • Отключите защиту csrf в конфигурации по умолчанию для сайта. Это включает в себя установку соответствующего значения ключа на карте в значение false, т.е. (wrap-defaults app-routes (assoc-in site-defaults [:security :anti-forgery] false))

Ответ 2

См. этот пример github . Примечательно внизу:

ring-defaults включает в себя анти-подделку по умолчанию для запросов POST (и другие, которые изменяют данные).

Я думаю, вам нужно изменить свое использование значений по умолчанию, если вы этого не хотите:

wrap-defaults routes site-defaults

Если вы не хотите его отключать, вам нужно либо отправить форму со скрытым полем с маркером, либо передать ее в заголовке через X-CSRF-Token и X-XSRF-Token. Подробнее см. Промежуточное программное обеспечение кольца docs для кольцевой защиты от подделки.

Ответ 3

добавьте скрытое поле в вашу форму, например, используйте команду enlive-html:

(ns xxx.html
  (:use [net.cgrand.enlive-html])
  (:require [clojure.string :as str]
            [ring.util.anti-forgery :refer [anti-forgery-field]]))

(deftemplate render-page "base.html"
  [settings]
  [:form#my-form] (append (html-snippet (anti-forgery-field)))
  ...
)

или отключить его, а не рекомендовать, как:

(открыть приложение (wrap-defaults app-routes (связанный с сайтом-defaults [: security: anti-подделка] false)))