http-redirectclojurecompojurering

Ring.util.response/redirect does not redirect site


I have a master page that displays the navbar, and copyright information, as well as handling logins. It gets the user profile, and passes it to the content function, or nil if the user is not signed in. So, for pages that I'd like to require sign in, I am going to have a check at the top, and redirect if the user is not signed in. The namespace declaration includes

(ns kandj.views.content
  (:require [ring.util.response :as response]))

For the content function, I have the following code:

(defn profile [g-profile]
  (if (nil? g-profile)
    (do (response/redirect "/" 307)
        (println "redirecting"))))

It prints redirecting to the console, but it does not actually redirect. I have variously tried using a string for the redirect code "307", and excluding it to use the default of 302. Nothing I have tried causes the page to redirect. What am I doing wrong?


Solution

  • You need to have your response/redirect as the last expression otherwise your handler returns nil which is the result of println expression.

    However, I think you should handle such cross-cutting concerns systematically instead of adding security related logic to each of your pages. The idiomatic approach is to use ring's middleware.

    You could write your own middleware handler which would know if the requested URL requires the user to be authenticated or not and pass through to the page render or redirect to the login page.

    For example:

    (defn authenticated? [request]
      ... your logic to check if the user is authenticated or not...)
    
    (defn secured-url? [request]
      ... your logic for determining if the requested page requires authenticated user...)
    
    (defn wrap-user-auth-check [handler]
      (fn [request]
        (if (and (secured-url? request)
                 (authenticated? request))
          (handler request)
          (response/redirect "/"))))
    
    (def app
      (-> handler
        (wrap-user-auth-check)))
    

    You might also take a look at a library for handling web app security for ring: friend.