How can I apply a middleware only on certain route? For example GET /userinfo
will need to authenticate a user first, whereas GET /somethingelse
won't require an access token at all.
Is path + method matching on the middleware is the way to go here?
@hawari.rahman17 many routing libs support this out-of-the-box, some samples: Compojure-api (macros):
(context "/api" []
:middleware [wrap-api]
(GET "/userinfo" []
:middleware [wrap-auth]
(ok ...))
(GET "/somethingelse" []
(ok ...)))
Reitit (data):
["/api" {:middleware [wrap-api]}
["/userinfo" {:get {:middleware [wrap-require-auth]
:handler ...}}]
["/somethingelse" {:get ...}]]
@ikitommi I've found that routes
in compojure is quite extendable, I ended up doing something like this:
(def restricted-routes
(-> (routes (GET "/protected-path" [] protected-fn))
(wrap-routes authorize)))
(defroutes app-routes
(GET "/unprotected-routes" [] "Hello")
restricted-routes)
I think you don’t need the routes
within the restricted-routes
.
My problem is sometimes in the same context, there exists a route that doesn't need to be authorized first
yes, but that’s to way to do it with Compojure. Compojure-api just adds sugar for it, e.g. the :middleware
key.
oh, then, yes.
if you are using nginx-clojure, you should be carefull with wrap-routes
. It uses mutable request maps and the wrap-routes
doesn’t work with it.
I mean, I'm not using nginx-clojure
but I'd like to know what I'd signed up for with wrap-routes
https://github.com/nginx-clojure/nginx-clojure/issues/182#issuecomment-318829347
e.g. wrap-routes
adds “call me if the path matches” info to the request. As the request is mutable, the info is still present in the request for the next routes. Next route will see that and invoke the mw. Kinda fatal.
So in other words, even if the path matches the routes not listed in restricted-routes
, the middleware authorize
will still gets invoked?
Wow, thanks for the warning @ikitommi, I'll be sure to remember that
yes, it gets called for the next route by Compojure. np.