首页 > 解决方案 > OAuth 回调 URL 与 nginx 代理服务器行为不兼容

问题描述

在过去的 3 天里,我花了很大一部分时间尝试互联网上的所有解决方案,并感到绝望。这是问题陈述:

我有一个包含三个服务的 Dockerized 应用程序:

我的 Web 应用程序要求用户通过相当标准的 OAuth 流程使用他们的 GitHub 帐户登录。这在没有nginx. 用户单击“使用 github 登录”按钮,将他们发送到 GitHub 以授权应用程序,并将其重定向回完成页面。

在此处输入图像描述

我将“授权回调 URL”填写为http://localhost:8000。如果没有 Nginx,我可以导航到 localhost 上的应用程序,单击按钮,并在授权后重定向回我在 localhost 上的应用程序。

使用 Nginx,我总是会因错误而失败(控制台中的 nginx):

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

这是我的 Nginx 配置:

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;
    }
}

这是我的 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:

我的预感是它在没有 Nginx 的情况下工作但与 Nginx http 服务器无关的原因与重定向有关,因为 Nginx 正在侦听一个端口,然后将其转发到另一个端口。GitHub 的 doc 专门说重定向 URI 需要和注册的回调 url 完全一样。我还使用了检查器工具,这些是我的请求标头:

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

我用 Nginx 得到的错误消息(再次强调它就像一个魅力,没有 nginx 10 次中的 10 次没有错误)是:

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

作为附加细节,我正在使用该social-auth-app-django软件包,但这无关紧要。

进一步的故障排除

经过无数小时的探索,我在本地调试模式下运行它,这次密切监视我的请求信息。当使用点击链接通过 OAuth 向 GitHub 授权时,这是请求以及所有标头信息:

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'

立即让我印象深刻的是HTTP_HOSTHTTP_REFERRERSERVER_NAME的值。对我来说也很有趣的是错误消息说:

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 而不是http://localhost:8000只有http://localhost,这看起来像是一个很大的暗示,表明我没有正确配置东西。任何线索或帮助都会有所帮助!

我试过的资源

像这样的StackOverflow 线程似乎很有希望,但像这样的类似问题除了解释错误外没有收到任何有意义的回应。

标签: djangodockernginxoauthdjango-socialauth

解决方案


推荐阅读