Fork me on GitHub
#ring
<
2019-12-31
>
Santiago10:12:29

I'm using compojure for an API. All is fine except I can't get access to the original JSON payload from POST requests, which I need for verifying requests. Is this done by changing middlewear?

AJ Jaro15:12:14

@slack.jcpsantiago Are you capturing the request argument to the route? For a GET macro, they should be in params and for a POST they should be in body

(GET "/basic/route/structure" request
  (let [params (:params request)]
    ...))

Santiago16:12:56

@ajarosinski Yes, I'm doing that already. What I need is the raw json payload, not the parsed payload as a clojure structure

AJ Jaro16:12:41

@slack.jcpsantiago Ah, hmm. That definitely is different than what I responded with, sorry. I don’t know exactly, but I have used the wrap-routes to add a middleware function and I think that still has the payload as a clojure structure. What are you trying to accomplish with the raw JSON instead of using the clojure structure?

Santiago16:12:01

I need to verify a request from Slack. To do that I need to build a signature from the raw json plus a timestamp they send in the header

ikitommi16:12:04

@slack.jcpsantiago you need to add a custom middleware that slurps the :body InputStream, places the slurped (raw) string under some key, e.g. :raw-body and either a) parses the body itself from JSON into :body-params, :json-params (or whatever your application expects) or b) re-creates the InputStream from the parsed body and let’s the normal body-parsing middleware read it.

ikitommi16:12:53

(fn [handler]
  (fn [request]
    (let [raw-body (slurp (:body request))
          request' (-> request
                       (assoc :raw-body raw-body)
                       (assoc :body (ByteArrayInputStream. raw-body)))]
      (handler request'))))

ikitommi16:12:27

something like that.

Santiago17:12:32

@ikitommi thanks! I'll try that out