Hi,
I'm integrating Friend with a set of routes. One route seems to consume the Friend login options even though it's not a Friend route. In detail, the following ordering results in a parameters map of {:user "" :password ""} being supplied to the Friend authentication function, though from the browser's perspective they're being POSTed with the correct values:
(compojure.core/defroutes user-routes
(http/GET "/account" req (resp/response (str "Account!..." req)))
(http/GET "/summary" req (resp/response (str "Summary!..." req))))
(compojure.core/defroutes ring-app
;; user routes
(compojure.core/context "/user" req (friend/wrap-authorize user-routes #{::user}))
;; admin routes
(http/GET "/admin" req (friend/authorize #{::admin}
"This page is only visible to administrators..."
(resp/response (str "Administrate!"))))
;; open access routes
(http/GET "/" {params :params} (resp/response (str params)))
(http/GET "/login" req (h/html5 pretty-head (pretty-body login-form)))
(friend/logout (http/ANY "/logout" request (resp/redirect "/")))
(route/not-found "Unpopulated link."))
(def secured-app
(compojure.handler/site
(friend/authenticate ring-app {:credential-fn #(do
(println (str "Testing user credentials..." %))
(creds/bcrypt-credential-fn users %))
:workflows [(workflows/interactive-form)]}))
)
I've included compojure.core under 'http'. Somewhere along the way the populated parameters list is being cleared from the login form (the auth function receives a map with the right keys and empty values, not an empty map).
Re-arranging the ring-app section of the routes to read
(compojure.core/defroutes ring-app
;; user routes
(compojure.core/context "/user" req (friend/wrap-authorize user-routes #{::user}))
;; admin routes
(http/GET "/admin" req (friend/authorize #{::admin}
"This page is only visible to administrators..."
(resp/response (str "Administrate!"))))
;; open access routes
(http/GET "/login" req (h/html5 pretty-head (pretty-body login-form)))
(friend/logout (http/ANY "/logout" request (resp/redirect "/")))
(http/GET "/" {params :params} (resp/response (str params)))
(route/not-found "Unpopulated link."))
resolves the issue. The only change is to move the GET "/" handler that just responds with supplied parameters in the body to the second-to-last position.
I understand that each route is tried in turn until one returns non-nil, but I thought that a route of "/" would only match that route. Is it that it matches all routes as the simplest route possible, and ignores subsequent URL segments? E.g. that most general matches should come last?
Thanks,
Oliver.