Как аутентифицировать пользователя из автономного интерфейса реакции с бэкэндом django (один и тот же домен, разные порты), используя стороннюю аутентификацию CAS? - PullRequest
1 голос
/ 01 июля 2019

Я устанавливаю бэкэнд django с Django REST framework для предоставления API, с аутентификацией, реализованной через сторонний сервер CAS.В настоящее время моя бэкэнд-аутентификация была успешно реализована (с использованием пакета django-cas-ng), что означает, что я могу реализовать разные разрешения для разных групп пользователей.Бэкэнд django по умолчанию обслуживается через localhost:8000.

Добавление автономного интерфейса реакции (по умолчанию localhost:3000) усложняет систему аутентификации.Запросы (реализуемые axios), отправляющие с порта 3000 на порт 8000, не могут аутентифицироваться.

Я пытался npm run build создать статические файлы и интегрировать их с django.В пределах одного и того же порта 8000 все аутентификация и разрешения работают нормально.

Может кто-нибудь подсказать, как реализовать аутентификацию через разные порты?

Ответы [ 2 ]

1 голос
/ 01 июля 2019

Отправляя запросы к нескольким портам, вы нарушаете политику браузеров Политика одного источника .Это сделано из соображений безопасности.

Браузеры также позволяют обойти эту политику, настроив CORS .По сути, вам нужно вернуть заголовок с именем Access-Control-Allow-Origin из своего бэкэнда, чтобы сообщить браузеру, что вы доверяете входящему источнику.

Для получения дополнительной информации вы можете прочитать связанные страницы.


Во время разработки я использую эти параметры для прослушивания междоменных запросов:

# It may be a good idea to use appropriate values during production

ALLOWED_HOSTS = ['*']

CSRF_TRUSTED_ORIGINS = ['*'] # if you're serving your frontend 
                             # and backend under same domain and port
                             # during production, then you can remove
                             # this.

Затем у меня также есть промежуточное ПО, которое вводит необходимые заголовки CORS при каждом HTTP-запросе.

Это не требуется, если вы обслуживаете интерфейс и сервер на одном и том же домене и порте.Так что не стоит использовать это промежуточное ПО во время производства.Если необходимо, используйте соответствующие значения.

Я храню этот код в файле с именем middleware.py и храню его в том же каталоге, что и мой settings.py файл.

# project_name/project_name/middleware.py

from django.http import HttpResponse
from django.conf import settings

CORS_ALLOW_ORIGIN = getattr(settings, 'CORS_ALLOW_ORIGIN', '*')
CORS_ALLOW_METHODS = getattr(settings, 'CORS_ALLOW_METHODS', ['POST', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'])
CORS_ALLOW_HEADERS = getattr(settings, 'CORS_ALLOW_HEADERS', ['content-type', 'authorization'])
CORS_ALLOW_CREDENTIALS = getattr(settings, 'CORS_ALLOW_CREDENTIALS', True)
CORS_EXPOSE_HEADERS = getattr(settings, 'CORS_EXPOSE_HEADERS', ['content-type', 'location'])

class CorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def set_headers(self, response):
        response['Access-Control-Allow-Origin'] = CORS_ALLOW_ORIGIN
        response['Access-Control-Allow-Methods'] = ','.join(CORS_ALLOW_METHODS)
        response['Access-Control-Allow-Headers'] = ','.join(CORS_ALLOW_HEADERS)
        response['Access-Control-Allow-Credentials'] = 'true' if CORS_ALLOW_CREDENTIALS else 'false'
        response['Access-Control-Expose-Headers'] = ','.join(CORS_EXPOSE_HEADERS)

        return response

    def __call__(self, request):
        response = self.get_response(request)
        response = self.set_headers(response)
        return response

И, наконец, измените некоторые настройки, чтобы Django использовал это промежуточное ПО:

MIDDLEWARE = [
    # ... other middlewares ...

    'project_name.middleware.CorsMiddleware',
]

Внимание: Возможно, вам не понадобитсякод из этого ответа в производстве, если вы обслуживаете свой веб-интерфейс и бэкэнд в одном домене и порту.Но это все еще хорошая идея, чтобы узнать больше о CORS.

0 голосов
/ 02 июля 2019

Оказывается, потому что запрос, отправленный с localhost:3000 на localhost:8000, не содержит sessionid от файлов cookie, поэтому пользователь не сможет пройти аутентификацию.

Для axios установка опции withCredential будет включать HTTPOnly sessionid:

axios("example.com", {
  method: "post",
  data: someJsonData,
  withCredentials: true
})

Для стороны django ответ должен включать:

Access-Control-Allow-Credentials: true, 
Access-Control-Allow-Methods GET, POST, PUT, PATCH, DELETE, OPTIONS,
Access-Control-Allow-Headers Content-Type
Access-Control-Allow-Origin: http://localhost:3000 
// CORS_ALLOW_ORIGIN = ['*'] or CORS_ORIGIN_ALLOW_ALL = True will not work

Еще раз спасибо @xyres за предоставление информации CORS, и это действительно очень помогло при решении этой проблемы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...