Question

I'm trying to use Friend with Luminus (basically lib-noir), and I've found that my :credential-fn isn't being called at all. At first I thought maybe I added the middleware wrong, but I tried setting a custom :login-failure-handler to see if at least that worked and it did.

Here's how my app looks like:

(defroutes my-routes
  (GET "/login" [login_failed username]
       (login-page login_failed username))  ;; login-page just renders HTML form
  (GET "/logout" req
       (friend/logout* (resp/redirect (str (:context req) "/")))))

(defn login-failure-handler [req]
  (println "Failed")  ;; <-- get's printed and redirects no problem
  (redirect "/login?failed=Y"))

(defn credential-fn [creds-map]
  (println creds-map)  ;; <-- doesn't get printed at all
  {:identity "test" :roles [::user]})

;; define custom wrapping middleware as noir's middleware/app-handler does
;; its own thing with routes + middleware
(defn authenticate [handler]
  (friend/authenticate
    handler
    {:workflows [(workflows/interactive-form
                   :credential-fn credential-fn
                   :login-failure-handler login-failure-handler)]}))

(defn debugger [handler]
  (fn [req]
    (println req)
    (handler req)))

(def app (middleware/app-handler
          ;; add your application routes here
          [my-routes]

          ;; add custom middleware here
          :middleware [debugger authenticate]

          ;; add access rules here
          :access-rules []

          ;; serialize/deserialize the following data formats
          ;; available formats:
          ;; :json :json-kw :yaml :yaml-kw :edn :yaml-in-html
          :formats [:json-kw :edn]))

I also added a debugger middleware, that just prints out the request map, and I've noticed that it doesn't print anything at all when I click on my login form's submit button (i.e. no POST request is happening). It just immediately prints out the GET to the login-failure-handler.

What did I miss?

Was it helpful?

Solution

Turns out my login form was incorrect. Friend specifically expects 2 form params from the POST request, username and password. So the login form needs to have those two fields. There doesn't seem to be a way to customise those fields on Friend's side, which I think is a flaw.

OTHER TIPS

You need to pass your credential-fn to friend/authenticate like this:

(friend/authenticate
  handler
  {:credential-fn credential-fn
   :workflows [(workflows/interactive-form)]})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top