我正在开发一个 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 %}
我设法通过禁用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"
...
]