Search code examples
pythonnginxhttp-redirectuwsgigoogle-oauth

google oauth 2.0 redirect_uri_mismatch (aws ec2 + route53 + nginx + uwgsi + flask + socketio)


I am getting a redirect_uri_mismatch whenever I try to use Google OAuth 2.0 on my website. I am using aws ec2 + route53 + nginx + uwgsi + flask + socketio

The Authorized redirect URIs: Had to add parenthesis to remove link.

  • (http)://example.net/auth/oauth2callback
  • (http)s://example.net/auth/oauth2callback
  • (http)://www.example.net/auth/oauth2callback
  • (http)s://www.example.net/auth/oauth2callback
  • (http)://localhost/auth/oauth2callback
  • (http)s://localhost/auth/oauth2callback

I've added a trailing "/" as well, but it doesn't seem to fix anything. I suspect its an nginx server setting issue or some connection issue between nginx -> uwsgi -> flask since the redirect uri what google's error page tells me exactly matches the URIs I've put into Google's OAuth settings.

Here is my nginx server configuration:

server {
    listen 80;
    server_name www.example.net;

    return 301 http://example.net;
}

server {
    listen 80;
    server_name example.net;

    return 301 https://example.net;
}

server {
    listen 443;
    server_name example.net;

    ssl on;
    ssl_certificate /certs.pem;
    ssl_certificate_key /private.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers BLANK;
    ssl_session_cache shared:SSL:50m;
    ssl_dhparam /dhparam.pem;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000";

    client_max_body_size 5M;

    location / {
        include uwsgi_params;

        uwsgi_pass unix:/filename.sock;
    }
}

I've looked into a lot of documents regarding this. Most people uses proxies and had to add some lines into the server configuration to handle this issue, but since I am not using such, I believe I don't have to put any of those in my configuration. (I tried a few solutions just in case, but they didn't seem to fix it still.)

Without using nginx and uwsgi, I was able to get the OAuth feature to work on localhost.

Thanks in advance!

Edit--
@TarunLalwani Okay, so I got it to make it half-work using proxy_pass. By only adding proxy_pass and nothing else, I can get to the Google OAuth login page. But once I authorize the login, it would redirect the user back to 127.0.0.1:5000 (Which is what I've set for proxy_pass). I think I have to do some reverse proxy setup. What I've added in the location block right after proxy_pass is this:

proxy_redirect off;
proxy_buffering off;

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

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

Now the reverse proxy seems to work as OAuth is broken again. But the OAuth 2.0 redirect the user to http:example.net/auth/oauth2callback instead of http:127.0.0.1:5000/auth/oauth2callback

I tested by adding each command line by line and restarting the server. Before adding proxy_set_header Host $host; is when I would get http://127.0.0.1:5000/auth/oauth2callback as a redirect uri and I would get http://example.net/auth/oauth2callback when I add that line in. Maybe the reason why OAuth is broken is because the user is getting redirected to http://example.net/auth/oauth2callback instead of https://example.net/auth/oauth2callback ?

Edit 2 --
By doing curl -v https://example.net/auth/oauth2callback I get the following:

*   Trying my.ip...
* Connected to example.net (my.ip) port 443 (#0)
* found 173 certificates in certs
* found 696 certificates in certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: example.net (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: CN=example.net
*        start date: Sun, 10 Sep 2017 22:18:00 GMT
*        expire date: Sat, 09 Dec 2017 22:18:00 GMT
*        issuer: C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3
*        compression: NULL
* ALPN, server accepted to use http/1.1
> GET /auth/oauth2callback HTTP/1.1
> Host: feelsbadman.net
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 302 FOUND
< Server: nginx/1.10.3 (Ubuntu)
< Date: Tue, 12 Sep 2017 07:32:36 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 819
< Connection: keep-alive
< Location: https://accounts.google.com/o/oauth2/auth?client_id=myid-asdfasdfasdf.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Fexample.net%2Fauth%2Foauth2callback&scope=email&access_type=offline&response_type=code&include_granted_scopes=true
< Strict-Transport-Security: max-age=31536000
<
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
* Connection #0 to host example.net left intact
<p>You should be redirected automatically to target URL: <a href="https://accounts.google.com/o/oauth2/auth?client_id=myid-asdfasdfasdf.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Fexample.net%2Fauth%2Foauth2callback&scope=email&access_type=offline&response_type=code&include_granted_scopes=true">https://accounts.google.com/o/oauth2/auth?client_id=myid-asdfasdfasdf.apps.googleusercontent.com&redirect_uri=http://example.net/auth/oauth2callback&scope=email&access_type=offline&response_type=code&include_granted_scopes=true</a>.

Solution

  • You site is https://example.net and your return url is going as http://example.net/auth/oauth2callback and being rejected.

    Please make sure the return url sent to google is https://example.net/auth/oauth2callback and it is set the same in the Authorized Redirect URI