Interceptors for session authentication
michaelwhitford opened this issue · 2 comments
I have an api that requires a session id header. You post a basic auth into /api/session and it returns a session id. Then further requests to other api endpoints need that session id as a header attached. I have the basic auth part working using an interceptor that adds the authorization header. I can't seem to figure out how to attach that session id header to further requests.
(def add-basic-auth-header
{:name ::add-basic-auth-header
:enter (fn [ctx]
(assoc-in ctx [:request :headers "Authorization"] "Basic base64encodedusernamepasswordhere"]))})
This interceptor works great. But how do I then use the session id in further requests? When I try to add a custom header when I call for the response it is not being added.
(def sid (:body (martian/response-for api :session)))
; sid is now a string of the session id
; this is not adding the session-id header to the request
(martian/request-for api :session {:headers {"session-id" sid})
{:method :post,
:url "https://example.com/api/session",
:insecure? true,
:headers
{"Authorization" "Basic base64encodedusernamepasswordhere",
"Accept" "application/json"},
:as :text}
This shows the authorization header, but not the session-id header. Looking at the code it seems this should add a header, but it is not. Is there a better way to handle this type of authentication using just interceptors?
Solved it using a custom param in the interceptor.
(def add-session-id
{:name ::add-session-id
:enter (fn [ctx]
(if-let [sid (get-in ctx [:params :session-id])]
(assoc-in ctx [:request :headers "session-id"] sid)
ctx))})
It sounds like the session-id header was not part of the specification in the api's descriptor. Martian will discard any params you pass it that are not part of the descriptor, and I think that happened here. Your interceptor is a good workaround for this.