Ошибка «URL Blocked» при входе в Facebook на рабочем сервере с использованием Nginx и Django - PullRequest
0 голосов
/ 05 марта 2020

Я использую Django OAuth (social-auth-app-django) для входа в Facebook. Он работает на localhost, но через некоторое время перестал работать на рабочем сервере. Когда я нажимаю sh кнопку входа в Facebook (https: /// oauth / login / facebook /) на рабочем сервере, меня перенаправляют на этот URL:

https://www.facebook.com/v3.2/dialog/oauth?client_id=2125271371046613&state=ngamzlnEBNjkivjZkZDJWyPi7MnyJ6z5&return_scopes=true&redirect_uri=https%3A%2F%2Flocalhost%2Foauth%2Fcomplete%2Ffacebook%2F

со следующим сообщением:

URL заблокирован: перенаправление не выполнено, поскольку URI перенаправления не включен в белый список в настройках OAuth клиента приложения. Убедитесь, что Client и Web OAuth Login включены, и добавьте все свои домены приложения в качестве действительного URI перенаправления OAuth. Блокировка заблокирована: это перенаправление не выполнено, поскольку URI перенаправления не включен в белый список в настройках OAuth клиента приложения. Убедитесь, что вход в систему Client и Web OAuth включен, и добавьте все свои домены приложений в качестве действительных URI перенаправления OAuth.

Мои действительные URI перенаправления OAuth: https://<my domain>/oauth/complete/facebook/

Похоже, что Django генерирует redirect_uri=https://localhost/auth/complete/facebook/ вместо redirect_uri=https://<my domain>/auth/complete/facebook/

Кроме того, если я добавлю https://localhost/oauth/complete/facebook/ к действительным URI перенаправления OAuth и pu sh кнопку входа в Facebook, я перенаправлюсь на

https://localhost/oauth/complete/facebook/?granted_scopes=public_profile&denied_scopes&code=AQDVoyWYftr-kU55VpWzUlyVOaFu80nWrdNhvnnakA-zxWRlGjwbBC4DMGyKasgDYtgtiPieqxO2H0H3z7mh-OxRuniJBDVOftCWnPNEKGfn8Tf-XExxYOcWdwAjhSUltgpm152fM13mgSDEGlzRvv6Dn_ccImV3c9Wsjr756jLdZr5cAdtIxv6tWLBsEBlynJmDZEYiucszOpain80WJCjAQAvyf3JdoCE0pb-YaxMFVa9c8KcN58s9Uif12trCc772AMQXnXDJxPauBl65bO5kRMJ4HPSj_-SXrMflWj5idehmM5OwsSGJakKsXgeYkshjnYycmc9bsy6NxAykV515&state=ngamzlnEBNjkivjZkZDJWyPi7MnyJ6z5#_=_

и (очевидно) получить сообщение «сервер не найден». Однако, если я затем вручную изменю localhost на <my domain> следующим образом:

https://<my domain>/oauth/complete/facebook/?granted_scopes=public_profile&denied_scopes&code=AQDVoyWYftr-kU55VpWzUlyVOaFu80nWrdNhvnnakA-zxWRlGjwbBC4DMGyKasgDYtgtiPieqxO2H0H3z7mh-OxRuniJBDVOftCWnPNEKGfn8Tf-XExxYOcWdwAjhSUltgpm152fM13mgSDEGlzRvv6Dn_ccImV3c9Wsjr756jLdZr5cAdtIxv6tWLBsEBlynJmDZEYiucszOpain80WJCjAQAvyf3JdoCE0pb-YaxMFVa9c8KcN58s9Uif12trCc772AMQXnXDJxPauBl65bO5kRMJ4HPSj_-SXrMflWj5idehmM5OwsSGJakKsXgeYkshjnYycmc9bsy6NxAykV515&state=ngamzlnEBNjkivjZkZDJWyPi7MnyJ6z5#_=_

У меня будет успешный вход.

Как сделать Django (или, возможно, * 1047) *) сгенерировать redirect_uri с <my domain> вместо localhost?

Я знаю, что это выглядит как дубликат social-auth-app- django состояния бэкэнда facebook с redirect_uri , но у них уже были правильные redirect_uri в их случае.

Вот мои Nginx настройки:

upstream citizen_engagement_portal {
  # fail_timeout=0 means we always retry an upstream even if it failed
  # to return a good HTTP response (in case the Unicorn master nukes a
  # single worker for timing out).

  server unix:/home/volunteer/xxx/yyy.sock fail_timeout=0;
}

server {
    listen 443 ssl;
    server_name <my domain> www.<my domain>;

    root /home/volunteer/xxx;

    location = /favicon.ico {
    access_log off;
    log_not_found off;
    }

    location /static/ {
        root /home/volunteer/serve;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/volunteer/xxx/yyy.sock;
    }

    location ~ /.well-known {
        root /var/www/letsencrypt;
        allow all;
    }

    location ~ /\.git {
    deny all;
    }

    location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        expires 7d;
        access_log off;
    }

    # security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;

    ssl_certificate /etc/letsencrypt/live/<my domain>/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<my domain>/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = <my domain>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name <my domain> www.<my domain>;

    location / {
        return 301 https://<my domain>$request_uri;
    }
}

1 Ответ

0 голосов
/ 06 марта 2020

Как было предложено @omab здесь

django-social-auth использует request.build_absolute_uri() для построения этого параметра redirect_uri. Проверяя django код для build_absolute_uri(), он вызывает get_host(), который проверяет HTTP_X_FORWARDED_HOST, HTTP_HOST или SERVER_NAME. Попробуйте определить любой из этих заголовков в вашем рецепте местоположения (я думаю, для этого есть proxy_set_header).

Я сделал это. В /etc/nginx/proxy_params

proxy_set_header X-Forwarded-Host '<my domain>';

В Django settings.py

USE_X_FORWARDED_HOST = True

Если я правильно понимаю, бэкэнд Django не знал, что он находится на <my domain> и Я заставил Nginx сказать Django, что.

...