在 GCP 计算引擎代码服务器上运行 django 时出现 CORS 问题

问题描述 投票:0回答:1

我正在开发一个 Django 项目。为此,我在我的个人笔记本电脑以及在 GCP 计算引擎上运行的远程代码服务器实例 (VS Code Remote) 上工作。

我在 https://dev.myweb.com (假网址)上运行代码远程,当通过端口 8000 中的

python manage.py runserver
运行 django 服务器时,内置代理允许我通过 https://dev 连接.myweb.com/proxy/8000

我可以毫无问题地访问第一页(base.html)(该页面中没有表格或请求)。但是当我点击登录(这会带来一个 POST 请求,我认为这是问题所在?)时,我收到如下错误:

Forbidden (403)
CSRF verification failed. Request aborted.

Help
Reason given for failure:

    Origin checking failed - https://dev.myweb.com does not match any trusted origins.
    
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django’s CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

Your browser is accepting cookies.
The view function passes a request to the template’s render method.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login.
You’re seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.

You can customize this page using the CSRF_FAILURE_VIEW setting.

我在远程 vscode 实例中启用了以下功能

if os.environ.get("ENV") == "DEV-remote":
    USE_X_FORWARDED_HOST = True
    FORCE_SCRIPT_NAME = "/proxy/8000"
    CORS_ALLOW_ALL_ORIGINS = True
    CORS_ALLOWED_ORIGINS = [
    "https://dev.myweb.com",
    ]
    CORS_ALLOW_METHODS = [
        'DELETE',
        'GET',
        'OPTIONS',
        'PATCH',
        'POST',
        'PUT',
    ]
    CORS_ORIGIN_WHITELIST = [
    "https://dev.myweb.com",
    ]

如果需要,以下 django 文件:

views.py

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.views import LoginView as LoginViewOrig
from django.shortcuts import render
from django.urls import reverse_lazy


class LoginView(LoginViewOrig):
    template_name = "login.html"
    form_class = AuthenticationForm
    success_url = reverse_lazy("home")

url.py

urlpatterns = [
    ...
    path("login/", LoginView.as_view(), name="login"),

login.html 模板

<!-- myapp/templates/myapp/login.html -->

{% extends 'base.html' %} {% block title %}Login - My Django App{% endblock %}
{% block header %}Login{% endblock %} {% block content %}
<div class="container">
    <div>
        <form method="post" action="{% url 'login' %}">
            {% csrf_token %} {{ form.as_p }}
            <button type="submit">Login</button>
        </form>
    </div>
</div>
{% endblock %}

django google-cloud-platform cors google-compute-engine
1个回答
0
投票

我设法通过禁用CORS(仅在DEV中)来解决这个问题https://stackoverflow.com/a/43841990/15254876

在您的应用程序中创建一个中间件(即/yourapp/middleware.py):

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

并与中间件的其余部分一起添加到settings.py中

MIDDLEWARE = [
...
    "yourapp.middleware.DisableCsrfCheck"
...
] 
© www.soinside.com 2019 - 2024. All rights reserved.