Testing the POST route with anti-fake and fake

I want to write a test for a simple POST request with ring.mock- something like this:

(testing "id post route"
    (let [response (app (mock/request :post "/" {:id "Foo"}))]
      (is (= 302 (:status response)))))

However, since I use middleware wrap-csrf, I get a status of 403, since I do not provide an anti-fake token.

Is there a way to write POST tests using ring.mockwithout disabling middleware wrap-csrf?

+4
source share
2 answers

What do you want to check? It’s not clear from your question, and it’s not clear why you shouldn’t disable anti-objective middleware at all.

  • -, CSRF (, , API ..).

  • , CSRF, CSRF, URL- (, ) , .

  • handler, "". , , .

+4

-, :

  • CSRF HTML, -.
  • Ring/Compojure . app, , CSRF, , . , CSRF.

, CSRF. :

(ns myapp.test.handler-test
  (:require [clojure.test :refer :all]
            [ring.mock.request :refer [request]]
            [net.cgrand.enlive-html :as html]
            [myapp.handler :refer [app]]))

(defn get-session
  "Given a response, grab out just the key=value of the ring session"
  [resp]
  (let [headers (:headers resp)
        cookies (get headers "Set-Cookie")
        session-cookies (first (filter #(.startsWith % "ring-session") cookies))
        session-pair (first (clojure.string/split session-cookies #";"))]
    session-pair))

(defn get-csrf-field
  "Given an HTML response, parse the body for an anti-forgery input field"
  [resp]
  (-> (html/select (html/html-snippet (:body resp)) [:input#__anti-forgery-token])
      first
      (get-in [:attrs :value])))

(defn get-login-session!
  "Fetch a login page and return the associated session and csrf token"
  []
  (let [resp (app (request :get "/login"))]
    {:session (get-session resp)
     :csrf (get-csrf-field resp)}))

(defn login!
  "Login a user given a username and password"
  [username password]
  (let [{:keys [csrf session]} (get-login-session!)
        req (-> (request :post "/login")
                (assoc :headers {"cookie" session})
                (assoc :params {:username username
                                :password password})
                (assoc :form-params {"__anti-forgery-token" csrf}))]
    (app req)
    session))

, /login __anti-forgery-token . CSRF , , curl, .

HTML, enlive, CSS, , .

, login!, , , , , :

 (deftest test-home-page-authentication
  (testing "authenticated response"
    (let [session (login! "bob" "bob")
          request (-> (request :get "/")
                      (assoc :headers {"cookie" session}))]
      (is (= 200 (:status (app request)))))))

, / bob bob, . , , , .

+3

All Articles