       (timbre/debugf "[%s +%4dms] %8.8s %s" status (- (System/currentTimeMillis) t0) method uri)
       response)))
 
-(def mobile-client-app
-  (-> (routes
-       resource-routes
-       mobile-client-routes)
-      (wrap-defaults (-> static-site-defaults
-                         assoc-cookie-conf))
+;; Here we define universal (as opposed to route-specific) middleware.
+(defn- wrap-universal-middleware
+  "Wrap the handler with middleware that is universally applicable across the site."
+  [handler options]
+  (-> handler
+      (wrap-session (options :session))
       wrap-log-requests))
 
+(def mobile-client-app
+  (-> (routes resource-routes mobile-client-routes)
+      (wrap-defaults static-site-defaults)
+      (wrap-universal-middleware {:session session-config})))
+
 (def desktop-client-app
-  (-> (routes
-       resource-routes
-       desktop-client-routes)
-      (wrap-defaults (-> static-site-defaults
-                         assoc-cookie-conf))
-      wrap-log-requests))
+  (-> (routes resource-routes desktop-client-routes)
+      (wrap-defaults static-site-defaults)
+      (wrap-universal-middleware {:session session-config})))
 
 (def api-server-app
   (-> (routes
-        modules/raw-handlers
+       modules/raw-handlers
 
-        (-> api-public-routes
-            (wrap-defaults (-> site-defaults
-                               (assoc-in [:security :anti-forgery] false)
-                               assoc-cookie-conf)))
+       (-> api-public-routes
+           (wrap-defaults (-> site-defaults
+                              (assoc-in [:security :anti-forgery] false))))
 
-        (-> modules/public-handler
-            (wrap-defaults (-> site-defaults
-                               (assoc-in [:security :anti-forgery] false)))
-            (wrap-restful-format :formats [:edn :transit-json]))
+       (-> modules/public-handler
+           (wrap-defaults (-> site-defaults
+                              (assoc-in [:security :anti-forgery] false)))
+           (wrap-restful-format :formats [:edn :transit-json]))
 
-        (-> sync-routes
-            (wrap-defaults (-> api-defaults
-                               assoc-cookie-conf
-                               assoc-csrf-conf)))
+       (-> sync-routes
+           (wrap-defaults (-> api-defaults assoc-csrf-conf)))
 
        (-> api-private-routes
-            (wrap-defaults (-> api-defaults
-                               assoc-cookie-conf
-                               assoc-csrf-conf)))
+           (wrap-defaults (-> api-defaults assoc-csrf-conf)))
 
        ;; this needs to be last, because the middleware will return
        ;; 401 if not authorized & hence not fall-through to other
        ;; routes
        (-> modules/private-handler
-           (wrap-defaults (-> site-defaults
-                              assoc-cookie-conf
-                              assoc-csrf-conf))
+           (wrap-defaults (-> site-defaults assoc-csrf-conf))
            (wrap-restful-format :formats [:edn :transit-json])))
       (wrap-cors :access-control-allow-origin (->>
-                                                [(when-let [site (env :site-url)]
-                                                   (re-pattern (java.util.regex.Pattern/quote site)))
-                                                 (when-let [mobile-site (env :mobile-site-url)]
-                                                   (re-pattern (java.util.regex.Pattern/quote mobile-site)))
-                                                 #"http://localhost:\d+"]
-                                                  (remove nil?))
+                                               [(when-let [site (env :site-url)]
+                                                  (re-pattern (java.util.regex.Pattern/quote site)))
+                                                (when-let [mobile-site (env :mobile-site-url)]
+                                                  (re-pattern (java.util.regex.Pattern/quote mobile-site)))
+                                                #"http://localhost:\d+"]
+                                               (remove nil?))
                  :access-control-allow-credentials true
                  :access-control-allow-methods [:get :put :post :delete])
       wrap-edn-params
-      wrap-log-requests))
+      (wrap-universal-middleware {:session session-config})))

   [ring.middleware.defaults :refer [wrap-defaults api-defaults secure-site-defaults site-defaults]]
   [ring.middleware.format :refer [wrap-restful-format]]
   [ring.middleware.edn :refer [wrap-edn-params]]
   [taoensso.timbre :as timbre]))

(def session-max-age (* 60 60 24 365))

               :content-types          true
               :default-charset        "utf-8"}})

(def session-config
  {:cookie-name "braid",
   :cookie-attrs {:secure (cond
                            (env :http-only) false
                            (= (env :environment) "prod") true
                            :else false)
                  :max-age session-max-age},
   :store session-store})

(defn- wrap-log-requests
  [handler]
  (fn [{uri :uri method :request-method :as request}]
