mapseed/platform

Fix social media logins when using SSL

Closed this issue · 7 comments

The only thing holding us back from using SSL on the server is that our social media logins break when SSL is on.

More specifically, the HTTP_REFERER header does not get set, which is used by our API to redirect the social media login page back to our app. Ideally, we shouldn't be using the HTTP_REFERER header anymore because it has a variety of issues. This may end up being a backend issue, but we should probably be able to fix it in this repo (frontend).

I will write a more thorough write up when I have some time, but here are some brief notes about the issue:

Here is the error we are getting in the console after trying to login over SSL:

Blocked loading mixed active content “http://api.heyduwamish.org/api/v2/my-username?callback=bootstrapCurrentUser&format=jsonp”
[Learn More]

Issue is largely due to our api's dependence on the python-social-auth==0.2.14 package, which relies on the HTTP_REFERER header, and is now deprecated. It's been split into multiple packages, with the following upgrade guide: https://github.com/omab/python-social-auth/blob/master/MIGRATING_TO_SOCIAL.md

Adding REDIRECT_IS_HTTPS = True fixes the location header value to be https instead of http. But this doesn't fix the issue. Here is the request url: /api/v2/users/current?format=jsonp&callback=bootstrapCurrentUser and the value of the location header: https://api.heyduwamish.org/api/v2/<username>?callback=bootstrapCurrentUser&format=jsonp

Some docs on this module: http://python-social-auth.readthedocs.io/en/latest/configuration/settings.html

I think I've made some progress on this. At least running locally with my ngrok setup, I can log in over https if I add the following to settings.py:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

See here: https://stackoverflow.com/questions/41483068/djangos-httpresponseredirect-is-http-instead-of-https
And here: https://docs.djangoproject.com/en/1.11/ref/settings/#secure-proxy-ssl-header

I'm not sure how nginx factors into my local setup exactly, but the same solution described in the post above works for me, and we're using nginx in production so I'm hopeful this might work.

It looks like ngrok sets the X-Forwarded-Proto header, which is probably why this fix works for me in my local setup. (+1 for using ngrok :) ). In production, I think we'll need to tweak our nginx.conf file to set this header properly, but I'm reasonably confident this is a workable solution.

Does this solution work for anyone else?

@goldpbear your solution looks really promising, thanks! I'll test it out tonight. Here is our nginx config that we're using in prod: https://github.com/modulitos/docker-shareabouts/blob/master/backend/nginx.conf

@modulitos I think I'm really close to getting it working. There's some nginx config stuff that I still don't have right though.

I redeployed the dev api off a branch with the SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') line included in settings.py.

I also added the following block to nginx.conf (in the block for https traffic):

location /api/v2/users/current {
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto https;
    proxy_pass http://smartercleanup-api:8010;
}

When I inspect the Location header from the original /users/current request, it now uses the correct scheme:

Location: https://smartercleanup-api:8010/api/v2/goldpbear?callback=bootstrapCurrentUser&format=jsonp

But, obviously, it's using the internal smartercleanup-api:8010 host instead of dev-api.smartercleanup.org.

I think there must be an nginx config setting that will fix this?

UPDATE: the following is working for me now!

In nginx.conf:

location /api/v2/users/current {
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-Host $host;
    proxy_pass http://smartercleanup-api:8010;
}

In settings.py:

USE_X_FORWARDED_HOST = True

BTW, you can use dev2.mapseed.org for testing this; it's configured to talk to the dev api.

I don't have much time now to test, but here are some other directives you can try adding to the config, if you haven't already:

        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;

^ Yes, this was on the right track. What ended up working was using X-Forwarded-Host.