-, :
- 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, . , , , .