# DiscourseConnect generates HTTP redirects even with force\_https on

**URL:** https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338
**Category:** Self-hosting
**Tags:** discourseconnect
**Created:** [May 24, 2024, 8:52pm UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338 "2024-05-24T20:52:28Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![matiasgarciaisaia](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/matiasgarciaisaia/32/509263_2.png) [@matiasgarciaisaia](https://meta.discourse.org/u/matiasgarciaisaia)
#### Post date: [May 24, 2024, 8:52pm UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338/1 "2024-05-24T20:52:28Z")

</div>

I’m running Discourse behind Traefik in a custom setup - giving Discourse its own VM is not an option here.

My Discourse doesn’t have SSL/Let’sEncrypt templates enabled, since Traefik won’t let plain HTTP requests reach the container - it’s set to redirect HTTP requests to HTTPs.

I’m having issues setting up [DiscourseConnect](https://meta.discourse.org/t/13045?silent=true), because, since the `Traefik -> nginx[Discourse]` request is sent over plain-text HTTP (because nginx doesn’t have SSL set up), the rule in `/etc/nginx/conf.d/discourse.conf` that tries `to preserve the proto, must be in http context` makes Discourse (the Rails app) to receive a plain-text HTTP request, thus returning a plain-text HTTP redirect to `/session/sso` - even if I have `force_https` enabled.

I think that’s the bug: regardless of my setup, with `force_https` enabled, Discourse should always generate HTTPs URLs - which it’s not doing.

I think the offending code is `application_controller#redirect_to_login`, but I haven’t dug that much into Discourse source code to be sure.

**Is this solvable in the code itself?**

As a workaround, I’m trying to add a rule patching the nginx’s `discourse.conf` to remove that rule.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [May 27, 2024, 7:31am UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338/2 "2024-05-27T07:31:54Z")

</div>

We should have some support for forwarded for headers you would use them to signal to NGINX what the origin is

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [May 27, 2024, 9:28am UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338/3 "2024-05-27T09:28:14Z")

</div>

Did you set

`proxy_set_header X-Forwarded-Proto https;`

---

<div class="post-metadata">

### Author: ![matiasgarciaisaia](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/matiasgarciaisaia/32/509263_2.png) [@matiasgarciaisaia](https://meta.discourse.org/u/matiasgarciaisaia)
#### Post date: [May 27, 2024, 4:00pm UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338/4 "2024-05-27T16:00:49Z")

</div>

What was easiest for me was to set an extra label in Discourse’s `app.yml` to tell my Traefik to add an `X-Forwarded-Proto: https` header, but then nginx would override that parameter with it’s own version.

And Discourse’s nginx config plays a role here:

> <https://github.com/discourse/discourse/blob/3b6d4c830fd1560dc9642c58371a57ddd9c95040/config/nginx.sample.conf#L33-L37>

There Discourse tries to guess the protocol from the original request (which, in my setup, is always plain-text since that’s what Traefik sends). And then uses that to [set the `X-Forwarded-Proto`](https://github.com/discourse/discourse/blob/3b6d4c830fd1560dc9642c58371a57ddd9c95040/config/nginx.sample.conf#L114) multiple times.

In the end, I edited my `containers/app.yml` to hard-code those headers to `https`:

```yaml
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  # - exec: rails r "SiteSetting.notification_email='no-reply@forum.cabana.network'"
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /# attempt to preserve the proto, must be in http context\nmap \$http_x_forwarded_proto \$thescheme {\n default \$scheme;\n "~https\$" https;\n\}/
     to: |
       # force https scheme so Discourse generates HTTPs links and redirects (ie, `/login`)
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: "$thescheme"
     global: "true"
     to: "https"
  - exec: echo "End of custom commands"

```

Once again, I think if there’s a `force_https` setting, Discourse-the-rails-app should honor it, regardless of what the reverse proxy or other parties handle or not.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [May 27, 2024, 4:33pm UTC](https://meta.discourse.org/t/discourseconnect-generates-http-redirects-even-with-force-https-on/309338/5 "2024-05-27T16:33:10Z")

</div>

> [@matiasgarciaisaia](#):
>
> tell my Traefik to add an `X-Forwarded-Proto: https` header

This is how we do it on our hosting platform; we have a load balancer layer that sets `X-Forwarded-Proto` for the downstream nginx+Discourse to consume.

We don’t need any additional shenanigans to make it work - I’m not sure what’s going wrong for you here.

> [@matiasgarciaisaia](#):
>
> Once again, I think if there’s a `force_https` setting, Discourse-the-rails-app should honor it, regardless of what the reverse proxy or other parties handle or not.

This is indeed what happens:

```plaintext
  def self.generate_sso(return_path = "/", secure_session:)
    sso = new(secure_session: secure_session)
    sso.nonce = SecureRandom.hex
    sso.register_nonce(return_path)
    sso.return_sso_url = Discourse.base_url + "/session/sso_login"
    sso
  end

```

and `base_url` comes from:

```plaintext
  def self.base_protocol
    SiteSetting.force_https? ? "https" : "http"
  end

  def self.base_url_no_prefix
    "#{base_protocol}://#{current_hostname_with_port}"
  end

  def self.base_url
    base_url_no_prefix + base_path
  end

```
