weavejester/ring-oauth2

cannot get the token

bongistan opened this issue · 4 comments

Hi! I am able to trigger the 2-factor process, and it seems to work all fine.
However I cannot read the received token!

I am using luminus framework with github-oauth2.

In the log I see this error:

Oct 10, 2019 12:48:45 PM org.apache.http.client.protocol.ResponseProcessCookies processCookies
WARNING: Invalid cookie header: "Set-Cookie: has_recent_activity=1; path=/; expires=Thu, 10 Oct 2019 11:48:44 -0000". Invalid 'expires' attribute: Thu, 10 Oct 2019 11:48:44 -0000

This cookie comes from the github oauth authorize response:
{"has_recent_activity":{"path":"/","value":"1"}}

This is my middleware section:

(defn wrap-base [handler]
  (-> ((:middleware defaults) handler)
      
      (wrap-defaults
       (-> site-defaults
           (assoc-in [:security :anti-forgery] false)
           ;(assoc-in [:session :store] (ttl-memory-store (* 60 30)))
           (assoc-in [:session :cookie-attrs :same-site] :lax)
           ))
      (wrap-params)
      (wrap-cookies)          
      (wrap-session)
      (wrap-csrf)
      (wrap-formats)
      (wrap-oauth2 my-oauth-profiles)
      wrap-internal-error))

This is how I try to get the token on the page-handler:

(defn personal-page [request]
  ; Once the user is authenticated, a new key is added to every request:
  ;   :oauth2/access-tokens
  (println "oauth2 tokens: " (-> request :oauth2/access-tokens :github))
  (layout/render request "test.html" {:all (all)}))

It looks like your middleware is incorrectly ordered. You've placed wrap-oauth2 outside of the parameter, session and cookie middleware, and you also have wrap-defaults, so you're adding most of your middleware twice over.

@weavejester Many thanks for your fast reply! Would you mind posting a sample that can be used that actually works? I have spent a lot of time re-ordering the middlewares, and this order worked at least to get the authentication process finished.

I am using the threading macro "->" therefore I thought that the last handler operates on a request that already was modified by the prior operators. If I put the oauth2 on the top, then it does not work at all.

I got it working!!! :-) THANK YOU SO MUCH!!
But perhaps you still want to add a little sample how it should be done.
At least to me the topic of how to organize the handler setup is quite confusing.
And googling for help did not help in my case at least. No samples for ring-oauth2
anywhere available :-(

(defn wrap-base [handler]
  (-> handler
      ;((:middleware defaults) handler)
      (wrap-oauth2 my-oauth-profiles)
      ;(wrap-params)
      ;(wrap-cookies)
      ;(wrap-session {:cookie-attrs {:same-site :lax 
      ;                              :http-only true}})
      ;(wrap-csrf)
      ;(wrap-formats)
      
      (wrap-defaults
       (-> site-defaults
           (assoc-in [:security :anti-forgery] false)
           ;(assoc-in [:session :store] (ttl-memory-store (* 60 30)))
           (assoc-in [:session :cookie-attrs :same-site] :lax)))
      wrap-internal-error))

When threading middleware, you're working from inside to outside. The Ring-OAuth2 relies on the session and params middleware, so it needs to be inside them, or in other words, come before.

You've got it right in your last example. wrap-oauth2 comes first, and then wrap-defaults adds the params, cookies and session middleware required. Finally wrap-internal-error will catch any exceptions, and therefore needs to be the outermost (or last) middleware.