I'm trying to add authentication to my api endpoints but it isn't working. One route is
["/api/sensor" :get [user/decode-jwt coerce-body-interceptor content-negotiation-interceptor entity-render db-interceptor sensor-query-form]]
and user/decode-jwt is:
(def decode-jwt
{:name :decode-jwt
:enter
(fn [context]
(println "in decode-jwt")
(if-let [auth-header (get-in context [:request :headers "authorization"])]
(try (->> auth-header
(auth/unsign-token)
(assoc-in context [:request :claims]))
(catch Exception _
(assoc context :response (unauthorized "The token provided is not valid"))))
(do
(println "in else")
(assoc context :response (unauthorized "no token provided"))
)
))})
If I don't provide an authorization header I see the following as expected:
in decode-jwt
in else
If I provide an invalid authorization header I see the following, also as expected:
in decode-jwt
in exception
however, in both cases, the server provides a valid response.
I thought that if the interceptor set the :response key no further interceptors would be called for the :enter phase
What am I misunderstanding?In my setup I have an auth interceptor that sets the response keyword on the context and it works. What does your unauthorized function return?
probably not important but your code sample doesn't include the println for "in exception" so it's hard to say what is happening in the latest version of your code.
I would also consider namespacing the claims keyword to ensure you don't conflict with anything else (not what you're asking about here but also noteworthy)
in your setup, how does setting :response indicate whether the authorization was valid or not? Or does it set :error if authorization failed?
Do I just add a second colon to namespace the claims keyword or something else?
In my case it looks something like (assoc context :response {:status 403 :body {...}) and an earlier interceptor negotiates the accepted content type and the body is coerced to the correct form to match the negotiated content type.
A second colon for the claims will namespace them, yes
my software's error responses include a body that explains the problem and recommends how to fix it.
403 is the "Forbidden" http status code
Maybe https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/401 "Unauthorised" is more appropriate for your use case
just setting a :response with a :status should be enough. You don't have to include a body
Here is the definition of unauthorized
(defn- unauthorized [text]
{:status 401
:headers {}
:body text})I updated from 0.8.0-alpha-1 to 0.8.0-beta-2 and now it works. I now realize providing the version I was using might have been a good thing to do