clojurebasic-authenticationcompojure

Composure + Swagger with basic authentication


I am trying to create a web service using compojure and swagger with a very simple basic authentication. I would like the authentication to be a single one, for instance, "mylogin" and "mypassword" for login and password. So far, what I have is

(ns my-api.handler
  (:require [compojure.api.sweet :refer :all]
            [ring.util.http-response :refer :all]
            [schema.core :as s]))

(s/defschema Request
  {:SomeData s/Str})

(s/defschema Result
  {:Results s/Str})

(defn dummy-return [request]
  {:Results "This is a dummy return"})

(def app
  (api
   {:swagger
    {:ui "/"
     :spec "/swagger.json"
     :data {:info {:title "A testing API"
                   :description "Compojure Api example"}
            :tags [{:name "api", :description "some apis"}]}}}

   (context "/api" []
     :tags ["api"]
     (POST "/API-Example" []
       :body [request Request]
       :return Result
       :summary "I want this to have a fixed basic authentication"
       (ok (dummy-return request))))))

And it works as expected. But how I would make this same API with basic authentication for one fixed user? I come from python and to do this is annoyingly easy with Flask. I was wondering if there is a simple and elegant solution without getting too much verbose.

I tried to include some stuff like :securityDefinitions {:login {:type "basic" :password "test"}} in the same level as :data but I could call the API even without authenticating it.

I started this project with lein new compojure-api my-api

Thanks for the help!


Solution

  • You can add a Ring handler that provides basic authentication. For example ring-basic-authentication.

    You add the handler globally to your app as follows:

    (require '[ring.middleware.basic-authentication :refer [wrap-basic-authentication]])
    
    (defn authenticated? [username pass]
      (and (= username "foo")
           (= pass "bar")))
    
    (def app 
       (-> routes
           ..
           (wrap-basic-authentication authenticated?))