Como posso habilitar CORS no Django REST Framework

Respostas:

144

O link que você referiu em sua pergunta recomenda o uso django-cors-headers, cuja documentação diz para instalar a biblioteca

pip install django-cors-headers

e adicione-o aos seus aplicativos instalados:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

Você também precisará adicionar uma classe de middleware para ouvir as respostas:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

Navegue pela seção de configuração de sua documentação, prestando atenção especial às várias CORS_ORIGIN_configurações. Você precisará definir alguns deles com base em suas necessidades.

Chris
fonte
2
conhece alguma outra forma de fazer isso, sem a necessidade de instalar uma nova dependência? Estou tentando criar uma classe de middleware agora
Julio Marins,
5
@JulioMarins, por que você escreveria sua própria versão quando ela está prontamente disponível e facilmente instalável, com 12 lançamentos, 21 contribuidores, mais de 800 estrelas e mais de 100 garfos?
Chris
2
Você realmente tem Access-Control-Allow-Origin: *razão , mas como a única necessidade de um CORS simples é um cabeçalho , não vejo por que carregar uma coisa inteira, vou colocar outra maneira de fazer isso em sua resposta para que ambos os métodos estejam disponíveis. referência: [link (] enable-cors.org/server.html )
Julio Marins
2
@JulioMarins, essa seria a abordagem da marreta. Se você olhar o link de configuração que forneci, verá que django-cors-headersé muito mais flexível do que isso. Se preferir criar sua própria turma, fique à vontade. Mas eu estaria usando essa biblioteca.
Chris,
4
@Chris, acho que você deve adicionar CORS_ORIGIN_WHITELIST para permitir o host de chamada.
Hakim
57
pip install django-cors-headers

e adicione-o aos seus aplicativos instalados:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

Você também precisará adicionar uma classe de middleware para ouvir as respostas:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',  
    'django.middleware.common.CommonMiddleware',  
    ...
)

CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3030',
] # If this is used, then not need to use `CORS_ORIGIN_ALLOW_ALL = True`
CORS_ORIGIN_REGEX_WHITELIST = [
    'http://localhost:3030',
]

mais detalhes: https://github.com/ottoyiu/django-cors-headers/#configuration

ler a documentação oficial pode resolver quase todos os problemas

likaiguo.happy
fonte
4
Adicionar as quatro linhas que você adicionou à resposta de @Chris foi necessário para que funcionasse para mim.
Matt D
5
Por que está CORS_ORIGIN_ALLOW_ALL = True, mas CORS_ORIGIN_WHITELISTainda está definido? Os documentos parecem fazer parecer que isso não é obrigatório e parece ser confuso para a resposta aqui.
Phoenix de
CORS_ORIGIN_ALLOW_ALL Se True, a whitelist não será usada e todas as origens serão aceitas.
BjornW
2
Também tenha em mente que 'corsheaders.middleware.CorsMiddleware',precisa estar no topo da lista, caso contrário, a conexão pode ser rejeitada antes de chegar a ela.
Sebastián Vansteenkiste
14

Você pode fazer isso usando um middleware personalizado, mesmo sabendo que a melhor opção é usar a abordagem testada do pacote django-cors-headers. Com isso dito, aqui está a solução:

crie a seguinte estrutura e arquivos:

- myapp/middleware/__init__.py

from corsMiddleware import corsMiddleware

- myapp/middleware/corsMiddleware.py

class corsMiddleware(object):
    def process_response(self, req, resp):
        resp["Access-Control-Allow-Origin"] = "*"
        return resp

adicione à settings.pylinha marcada:

MIDDLEWARE_CLASSES = (
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",

    # Now we add here our custom middleware
     'app_name.middleware.corsMiddleware' <---- this line
)
Julio Marins
fonte
Obrigado Julio! Seu código de middleware deve ser atualizado com a amostra de código @masnun. Além disso, a importação não funciona para mim, importando de. corrige o problema: from . import corsMiddleware
Pavel Daynyak
12

Caso alguém esteja voltando a esta questão e decidindo escrever seu próprio middleware, este é um exemplo de código para o novo estilo de middleware do Django -

class CORSMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"

        return response
Masnun
fonte
7

Para versões do Django> 1.10, de acordo com a documentação , um MIDDLEWARE personalizado pode ser escrito como uma função, digamos no arquivo: yourproject/middleware.py(como irmão de settings.py):

def open_access_middleware(get_response):
    def middleware(request):
        response = get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"
        return response
    return middleware

e, finalmente, adicione o caminho python desta função (escrito a raiz do seu projeto) para a lista MIDDLEWARE em seu projeto settings.py:

MIDDLEWARE = [
  .
  .
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
  'yourproject.middleware.open_access_middleware'
]

Mole-mole!

Dhruv Batheja
fonte
A abordagem postada antes usa MIDDLEWARE_CLASSES e não MIDDLEWARE. Essa técnica funciona, então o downvote foi desnecessário :) @JulioMarins
Dhruv Batheja
1
cara, a solução é a mesma. Você está discutindo sobre a implementação na versão Django. Seu código também está com indentação incorreta open_access_middleware.
Julio Marins
4

Bem, eu não conheço caras, mas:

usando aqui python 3.6 e django 2.2

Renomear MIDDLEWARE_CLASSES para MIDDLEWARE em settings.py funcionou.

jnowak
fonte
3

Abaixo estão as etapas de trabalho sem a necessidade de nenhum módulo externo:

Etapa 1: crie um módulo em seu aplicativo.

Por exemplo, vamos supor que temos um aplicativo chamado user_registration_app . Explore user_registration_app e crie um novo arquivo.

Vamos chamar isso de custom_cors_middleware.py

Cole a definição de classe abaixo:

class CustomCorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"

        # Code to be executed for each request/response after
        # the view is called.

        return response

Etapa 2: registrar um middleware

No arquivo settings.py do seu projeto, adicione esta linha

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

Por exemplo:

  MIDDLEWARE = [
        'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
         ...
        'django.middleware.common.CommonMiddleware',

    ]

Lembre-se de substituir user_registration_app pelo nome de seu aplicativo onde você criou seu módulo custom_cors_middleware.py.

Agora você pode verificar se ele adicionará os cabeçalhos de resposta necessários a todas as visualizações no projeto!

user3785966
fonte
0

Django = 2.2.12 django-cors-headers = 3.2.1 djangorestframework = 3.11.0

Seguir a instrução oficial não funciona

Finalmente, use a maneira antiga de descobrir.

ADICIONAR:

# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening
#proj/settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'proj.middlewares.CsrfExemptSessionAuthentication',
    ),
}
CK
fonte