Fork me on GitHub
#reitit
<
2019-04-02
>
Daw-Ran Liou03:04:00

Hi I’m trying to implement a ring-router to login a user with basic http authorization. I got something odd if I use header parameter like:

["/login"
       {:post {:summary "log in the user and create a session"
               :parameters {:header {:Authorization string?}}
               :response {200 {:body {:result keyword?
                                      :message string?}}}
               :handler
               (fn [req] (auth/login! req))}}]

The response would be:
{
  "spec": "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:spec$61926/Authorization]), :type :map, :leaf? false})",
  "problems": [],
  "type": "reitit.coercion/request-coercion",
  "coercion": "spec",
  "value": {
    "referer": "",
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
    "authorization": "Basic Zm9vOjEyMzQ1Njc=",
    "host": "localhost:3000",
    "content-length": "0",
    "cookie": "io=CEe1y2Mkyr9jFrv4AAAC; tabstyle=html-tab; csrftoken=RNIjyBynjIHIbARf5eqQh79iBo49rojWwe9w20Fm382NN5aOjxDIS3f1QWCTFV4s; secret=872a63ba-3d80-495d-9885-2b020a26f0b5; ring-session=d4692218-ce09-4631-b3e1-e2406d2ae83b; JSESSIONID=fPacF0-MFe79UBeqBDBf9-ONVbTUE5MURVLCxFBt",
    "accept-encoding": "gzip, deflate, br",
    "content-type": "application/json",
    "origin": "",
    "connection": "keep-alive",
    "accept-language": "en-US,en;q=0.9,zh-TW;q=0.8,zh;q=0.7",
    "accept": "application/json"
  },
  "in": [
    "request",
    "headers"
  ]
}

Daw-Ran Liou03:04:24

If I remove the :parameters key from the map, then it is working

Daw-Ran Liou04:04:26

What’s happening here? And what does this response mean?

Daw-Ran Liou04:04:17

Any guidance is appreciated.

martinklepsch07:04:55

@dawranliou maybe try "Authorization"? or "authorization"

ikitommi07:04:40

@dawranliou @martinklepsch Just tested, the problem is that ring lowercases all headers, so it’s passed as :authorization. Declaring {:header {:authorization string?}} makes the api-docs require a authorization header, which is not right (but works). Hmm.

ikitommi07:04:45

I guess there are options: 1) header-params are declared as String, e.g. {:headers {"Authorization" string?}} 2) as CamelCase keywords, the coercion reads them correctly {:headers {:Authorization string?}} 3) as lower-case keywords, camel-cased for api-docs {:headers {:authorization string?}} 4) something else

vielmath14:04:16

Hi there, I'm migrating a pedestal app to use reitit and I'd like to use reitit.http.interceptors.exception/exception-interceptor but I'ts not compliant to pedestal's 2-arrity error Is there a trick to use it? Should I write a PR with a multi-arrity version that could be used with pedestal also?

Daw-Ran Liou14:04:18

@martinklepsch @ikitommi Thanks for helping! For now I’ll settle for :authorization. Would you share how you figure this out? I spent some time troubleshooting but still couldn’t understand the response. I was guessing something was happening to coerce-request-middleware but didn’t know how to go further.

ikitommi16:04:47

@vielmath there was a discussion about it, just wrote one solution suggestion as an issue: https://github.com/metosin/reitit/issues/250. Bit hacky, but should work and would be transparent. What do you think?

vielmath08:04:13

Looks good. I'll give it a try while waiting for feedback on the issue. Thanks @ikitommi

ikitommi17:04:23

@dawranliou the spec error doesn’t indicate that very well, but I just know the ring-spec (https://github.com/ring-clojure/ring/blob/master/SPEC), which says they are lowercased. There is also an utility in reitit to inspect request (or contexts with interceptors), might help debugging these, see https://cljdoc.org/d/metosin/reitit/0.3.1/doc/ring/default-middleware#inspecting-requests

Daw-Ran Liou17:04:30

That's very helpful! Thank you very much for your time 🙂