luminus

Edward Ciafardini 2022-08-27T19:06:20.893019Z

I have my luminus app deployed to heroku with an SSL certificate- so going to https://www.my http://app.com (fake link) works and shows the lock icon in browser But if I access the link without the https:// appended to the URL, http is used and there is an “unsecured connection” warning. Is there a way in luminus to redirect all requests to my URL to use https?

Marius 2022-09-17T12:36:49.265089Z

Actually there is a much easier way, almost trivial. It is possible to enable a Strict-Transport-Security header and redirect to HTTPS using the Ring config. No need to add ring-ssl. Just add the lines (assoc-in [:security :hsts] true) (assoc-in [:security :ssl-redirect] true) like this in your middleware.clj:

(wrap-defaults
        (-> site-defaults
            (assoc-in [:security :anti-forgery] true) 
            (assoc-in [:session :store] session/store)
            (assoc-in [:security :hsts] true)
            (assoc-in [:security :ssl-redirect] true)))
      wrap-internal-error))

💫 1
Ted Ciafardini 2022-09-17T12:38:55.585679Z

awesome. Trivial if you know about it 🤷‍♂️ - where did you find this? thanks!

Marius 2022-09-17T12:41:07.188079Z

True 🙂 I was looking into what function wrap-defaults from ring.middleware.defaults does, that’s where I found it.

1
Marius 2022-09-17T12:42:06.976779Z

Only problem right now is that it is enabled in dev mode as well, and https://localhost:3000 does not work

Ted Ciafardini 2022-09-17T12:42:19.340589Z

I was wondering if that would be a problem

Ted Ciafardini 2022-09-17T12:42:48.292729Z

Probably a cond-> that checks the env var

Ted Ciafardini 2022-09-17T12:42:53.065099Z

let me try something

Marius 2022-09-17T12:53:04.076889Z

Yeah… (assoc-in [:security :ssl-redirect] (get defaults :ssl-redirect true))))

Marius 2022-09-17T12:53:21.310149Z

and then :ssl-redirect false in env.clj

Ted Ciafardini 2022-09-17T12:53:38.350699Z

ahhh nice

Ted Ciafardini 2022-09-17T12:53:47.475289Z

I had a gnarly cond-> going lol

Marius 2022-09-17T12:54:57.845399Z

It’s probably better to disable HSTS for localhost as well

Marius 2022-09-17T12:56:32.851919Z

I had it enabled and got redirected (although broken), but now my browser will immediately redirect to HTTPS due to HSTS… the max-age is set for 1 year — I guess I should find out how to reset this 😂

Ted Ciafardini 2022-09-17T12:57:27.158299Z

lolll

Ted Ciafardini 2022-09-17T13:02:55.088889Z

Are you sure about (get defaults :hsts true)? This will default to true even if it isn’t present

Marius 2022-09-17T13:05:38.818439Z

My idea was that it isn’t present on production, therefore to enable it on production, it must be true

Ted Ciafardini 2022-09-17T13:06:04.721939Z

I’m trying this out:

(defn wrap-base [handler]
  (let [config-file (:conf (source/from-system-props))]
   (-> ((:middleware defaults) handler)
      (wrap-defaults
       (-> site-defaults
           (assoc-in [:security :anti-forgery] false)
           (assoc-in [:session :store] (ttl-memory-store (* 60 30)))
           ;Enable HTTPS redirect...
           ;TODO - look into these settings and what they mean:
           (assoc-in [:security :hsts] (if (= config-file "dev-config.edn")
                                         false
                                         true))
           (assoc-in [:security :ssl-redirect] (if (= config-file "dev-config.edn")
                                                 false
                                                 true))))
      wrap-internal-error)))

Ted Ciafardini 2022-09-17T13:08:19.697499Z

ack - assoc’ing in ssl-redirect broke my page when deployed 🌚

Marius 2022-09-17T13:08:52.908239Z

your version looks a bit too complicated in checking the config file name to figure out whether it’s dev or not

Marius 2022-09-17T13:10:25.623389Z

what exactly broke your page?

Ted Ciafardini 2022-09-17T13:10:47.639149Z

This page isn't  redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

Ted Ciafardini 2022-09-17T13:10:53.648389Z

http://www.fpblogg.com

Ted Ciafardini 2022-09-17T13:11:20.184999Z

You don’t have this problem in production?

Ted Ciafardini 2022-09-17T13:12:04.347869Z

“More than 20 redirections”

Marius 2022-09-17T13:14:46.132609Z

You’re faster than me, I’m deploying… 😄

Marius 2022-09-17T13:16:56.612149Z

Ah ok, seems like the App does not know it’s being accessed via HTTPS already and therefore already redirects. I will have the same issue then.

Ted Ciafardini 2022-09-17T13:19:05.933269Z

Take a look at this defaults.clj - the wrap-defaults function

Ted Ciafardini 2022-09-17T13:19:27.074689Z

I think it’s already doing this for us, we just need to set up the config correctly

Marius 2022-09-17T13:20:33.475619Z

Yeah, I was just looking at it too, try setting :proxy to true to enable wrap-forwarded-scheme

Ted Ciafardini 2022-09-17T13:26:11.138149Z

yah, deploying now to see if it works 🤞

Marius 2022-09-17T13:29:21.433679Z

Works for me now 👍

Ted Ciafardini 2022-09-17T13:29:41.085459Z

Can I see yr wrap-base fn?

Marius 2022-09-17T13:29:49.607479Z

1st redirect is from the app (HTTP 301), on a subsequent visit it’s a browser redirect (HTTP 307)… as expected

Marius 2022-09-17T13:30:30.979419Z

(defn wrap-base [handler]
  (-> ((:middleware defaults) handler)
      (wrap-defaults
        (-> site-defaults
            (assoc-in [:security :anti-forgery] true)
            (assoc-in [:session :store] session/store)
            (assoc-in  [:security :hsts] (get defaults :hsts true))
            (assoc-in [:security :ssl-redirect] (get defaults :ssl-redirect true))
            (assoc-in [:proxy] (get defaults :proxy true))))
      wrap-internal-error))

Marius 2022-09-17T13:31:15.680719Z

and my config in env.clj

:hsts false
   :ssl-redirect false
   :proxy false})

Ted Ciafardini 2022-09-17T13:31:50.827859Z

how did you know defaults would have the vals from config?

Marius 2022-09-17T13:32:44.658279Z

because I added them in env.clj

Ted Ciafardini 2022-09-17T13:33:11.367379Z

Can I see that?

Marius 2022-09-17T13:34:01.624639Z

(ns myapp.env
  (:require
    [selmer.parser :as parser]
    [clojure.tools.logging :as log]
    [myapp.dev-middleware :refer [wrap-dev]]))

(def defaults
  {:init
   (fn []
     (parser/cache-off!)
     (log/info "\n-=[myapp started successfully using the development profile]=-"))
   :stop
   (fn []
     (log/info "\n-=[myapp has shut down successfully]=-"))
   :middleware wrap-dev
   :hsts false
   :ssl-redirect false
   :proxy false})

Ted Ciafardini 2022-09-17T13:34:50.605249Z

ahhhh, I see now

Ted Ciafardini 2022-09-17T13:35:21.680089Z

I was trying to pull these from the config file. I wonder if there’s a way to do that. This works though

Ted Ciafardini 2022-09-17T13:35:23.148759Z

thanks a lot!

Marius 2022-09-17T13:37:50.205619Z

I would only pull things from a config file which need to change without recompilation and can be read from the environment, so e.g. database URL

Marius 2022-09-17T13:38:17.152659Z

but in this case the production build will never have HTTPS switched off — I guess 🙂

Ted Ciafardini 2022-09-17T13:38:41.139419Z

Ok, cool. This is the first website I’ve ever made, so I don’t really know best practices

Ted Ciafardini 2022-09-17T13:38:49.138139Z

Thanks for all your help

Marius 2022-09-17T13:39:53.061059Z

if you look at core.clj, there is a line like this: (update :port #(or (-> env :options :port) %)) This is reading the port from the config file

Ted Ciafardini 2022-09-17T13:40:36.041609Z

I set up a prod-only DATABASE_URL for the postgres instance by the skin of my teeth

Ted Ciafardini 2022-09-17T13:40:43.804839Z

Got ya

Marius 2022-09-17T13:41:24.243299Z

😂 👍

Marius 2022-09-10T11:28:44.944789Z

Cool, thank you very much!

Edward Ciafardini 2022-09-01T22:21:27.537729Z

Thanks - I think I found something 😁

Marius 2022-09-09T08:45:48.910409Z

@esciafardini I have the same issue and would also be interested in your solution 🙂

Ted Ciafardini 2022-09-09T11:39:00.502609Z

this is what I found: https://github.com/ring-clojure/ring-ssl I haven’t tried it yet- but it’s on my todo list.

Ted Ciafardini 2022-09-09T11:39:05.607369Z

Let me know if you have any luck 🙂

Eugen 2022-08-29T08:00:24.782289Z

also look at HSTS header https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security

Eugen 2022-08-29T08:01:16.236219Z

be careful with hsts, browsers are kind of strict from what I remember

Eugen 2022-08-29T08:03:14.298819Z

bottom: line, you need to do it in your app. A high level solution is: Add a route / middleware ?! that checks schema = http . when that happens, either send HSTS and/or redirect to http . Maybe you can find a library that implements this logic ?!

Eugen 2022-09-02T08:08:02.105079Z

please share