4

I have spent a good part of the last 3 days trying every solution that is on the internet and feeling desperate. Here's the problem statement:

I have a Dockerized app with three services:

  • A django application with gunicorn (web)
  • A Nginx server (nginx)
  • PostgreSQL (db)

My web application requires user to log in with their GitHub account through a fairly standard OAuth process. This has always worked without nginx. User clicks on the "log in with github" button, sent them to GitHub to authorize the application, and redirects it back to a completion page.

enter image description here

I have "Authorization callback URL" filled in as http://localhost:8000. Without Nginx I can navigate to the app on localhost, click on the button, and upon authorization, get redirected back to my app on localhost.

With Nginx, I would always fail with the error (nginx in console):

GET /auth/complete/github/?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=nmegLb41b959su31nRU4ugFOzAqE8Cbl HTTP/1.1

This is my Nginx configuration:

upstream webserver {
    # docker will automatically resolve this to the correct address
    # because we use the same name as the service: "web"
    server web:8000;
}

# now we declare our main server
server {

    listen 80;
    server_name localhost;

    location / {
        # everything is passed to Gunicorn
        proxy_pass http://webserver;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
    }

    location /static {
        autoindex off;
        alias /static_files/;
    }

    location /media {
        alias /opt/services/starport/media;
    }
}

This is my Dockerfile:

version: '3.7'
services:
  web:
    build: .
    command: sh -c "cd starport && gunicorn starport.wsgi:application --bind 0.0.0.0:8000"
    volumes:
      - static_files:/static_files # <-- bind the static volume
    networks:
      - nginx_network
  nginx:
    image: nginx
    ports:
      - 8000:80
    volumes:
      - ./config/nginx/conf.d:/etc/nginx/conf.d
      - static_files:/static_files # <-- bind the static volume
    depends_on:
      - web
    networks:
      - nginx_network

networks:
  nginx_network:
    driver: bridge

volumes:
  static_files:

My hunch was that the reason it worked without Nginx but doesn't with the Nginx http server has got to do with the redirection since Nginx is listening to a port and then forwarding it to a different port. GitHub's doc specifically said that the redirect URI needs to be exactly the same as the registered callback url. I've also used the inspector tools and these are my Request headers:

GET /accounts/login/ HTTP/1.1
Cookie: ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Host: localhost:8000
User-Agent: Mozilla/5.0
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

The error message I get with Nginx (again, stressing that it works like a charm without error without nginx 10 out of 10 times) is:

http://localhost:8000/auth/complete/github/?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch

As an additional detail, I'm using the social-auth-app-django package but this should not matter.

Further troubleshooting

After countless hours of probing, I run this in local on debug mode and this time closely monitored my Request information. When use hits the link to authorize with GitHub via OAuth, this is the Request along with all the header information:

CSRF_COOKIE             'abc'
HTTP_ACCEPT             'text/html,application/xhtml+xml'
HTTP_ACCEPT_ENCODING    'gzip, deflate'
HTTP_ACCEPT_LANGUAGE    'en-us'
HTTP_CONNECTION         'close'
HTTP_COOKIE             ('csrftoken=...; ')
HTTP_HOST               'localhost'
HTTP_REFERER            'http://localhost:8000/accounts/login/?next=/'
HTTP_USER_AGENT         ('Mozilla/5.0')
HTTP_X_FORWARDED_FOR    '172.26.0.1'
HTTP_X_FORWARDED_PROTO  'http'
PATH_INFO               '/auth/complete/github/'
SERVER_NAME             '0.0.0.0'
SERVER_PORT             '8000'

QUERY_STRING    
'error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=NwUhVqfOCNb51zpvoFbXVvm1Cr7k3Fda'

RAW_URI 
'/auth/complete/github/?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=NwUhVqfOCNb51zpvoFbXVvm1Cr7k3Fda'

What immediately stood out to me was the value of HTTP_HOST, HTTP_REFERRER and SERVER_NAME. What's also interesting to me was the error message says:

http://localhost/auth/complete/github/?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=NwUhVqfOCNb51zpvoFbXVvm1Cr7k3Fda

Where instead of http://localhost:8000 it only has http://localhost, which looks like a big hint that I am not configuring things correctly. Any leads or assistance would help!

Resources I've tried

StackOverflow threads like this seems promising but similar questions like this receive no meaningful response except to explain the error.

9
  • In your question you state "With Nginx, I would always fail with the error:" I think you missed the error message. Commented Aug 21, 2019 at 10:45
  • Thank you for catching that Matt. Plenty of sleepless nights :( Fixed. Commented Aug 21, 2019 at 10:47
  • My initial thought was a trailing slash issue, with nginx redirecting. This was the first link I found which might confirm this. "Authorized redirect URIs needs to have the slash, i.e. localhost:8080 this fixes the issue. Source github.com/MrSwitch/hello.js/issues/347#issuecomment-168413303" This might make sense as django loves its trailing slashes so if the API is redirecting to a non / url some craziness might be happening with redirects Commented Aug 21, 2019 at 10:48
  • It does have a slash, in my screenshot you can see my redirect URI would be http://localhost:8000/auth/complete/github/ Commented Aug 21, 2019 at 10:51
  • :+1:, okay what port number is nginx running on locally on your machine? Is it port 8000 or something different? Wonder if you have a port number mismatch. Commented Aug 21, 2019 at 10:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.