CSRF 验证失败。请求被中止。 (CSRF 令牌在明显存在时未设置)

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

是的,我将 csrf 令牌添加到我的表单中,是的,我在表单中添加了 post 方法,是的,我检查了服务器发送 cookie 是否与客户端 cookie 匹配。另外,其他好的上下文可能是我的主页视图上有 loginrequiredMixin,因此在尝试访问它时它会将您重定向到登录页面,但不认为这是问题所在。

Django 说原因是它找不到 csrf 令牌,但我检查了 Django 源代码中的名称,它与密钥匹配,并且具有从服务器发送的匹配值,即

request_csrf_token = request.POST.get("csrfmiddlewaretoken", "")

这是我正在使用的表单,它们继承了 Django 默认注册和登录表单:

class LoginForm(AuthenticationForm):
def __init__(self, request=None, *args, **kwargs):
    super(LoginForm, self).__init__(request, *args, **kwargs)
    self.fields['username'].widget = forms.TextInput(attrs={'class': 'form-control', 'id': 'username'})
    self.fields['password'].widget = forms.PasswordInput(attrs={'class': 'form-control'})
    self.fields['remember_me'] = forms.BooleanField(
        required=False, 
        widget=forms.CheckboxInput(attrs={'class': 'custom-control-input', 'id': 'remember-me'})
    )

类 SignUpForm(UserCreationForm): 电子邮件 = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'})) 用户名 = forms.CharField(max_length=100, required=False, widget=forms.TextInput(attrs={'class': 'form-control'})) 密码1 = forms.CharField(label='密码', widget=forms.PasswordInput(attrs={'class': 'form-control'})) password2 = forms.CharField(label='确认密码', widget=forms.PasswordInput(attrs={'class': 'form-control'}))

我在这里迷失了,我做错了什么?

          <form method="POST" id="formAuthentication" class="mb-3">            
        <div class="input-group mb-3">
          {{ form.username|attr:"placeholder:Username"|add_class:'form-control' }}
          <button id="diceButton" class="btn btn-outline-secondary" type="button" onclick="rollDice()">
             <small>🎲</small>
          </button>
        </div>

        <div class="mb-3">
          {{ form.email|attr:"placeholder:Email"|add_class:'form-control' }}
        </div>
        <div class="mb-3">
          {{ form.password1|attr:"placeholder:Password"|add_class:'form-control' }}
        </div>
        <div class="mb-3">
          {{ form.password2|attr:"placeholder:Confirm Password"|add_class:'form-control' }}
        </div>

        <button class="btn btn-primary d-grid w-100">
          Sign up
        </button>
      {% csrf_token %}
      </form>

我的 Django 登录视图:

class LoginView(TemplateView):
form_class = LoginForm
template_name = "auth_login_basic.html"

def get_context_data(self, **kwargs):
    csrf_token = get_token(self.request)
    print("token (server) ", csrf_token)
    context = TemplateLayout.init(self, super().get_context_data(**kwargs))
    context.update(
        {
            "layout_path": TemplateHelper.set_layout("layout_blank.html", context),
            "form": self.form_class,
            "csrf_token": csrf_token,
        }
    )
    return context

def post(self, request, *args, **kwargs):
    print("request method: ", request.method)
    
    received_token = request.POST.get('csrfmiddlewaretoken', '')
    assert received_token == get_token(request), "CSRF token mismatch"
    form = self.form_class(request.POST)
    context = self.get_context_data(**kwargs)
    context['form'] = form

    if form.is_valid():
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        user = authenticate(request, username=username, password=password)

        if form.cleaned_data.get('remember_me'):
            print("Remember me True")
            request.session.set_expiry(1209600)
        else:
            print("Remember me False")
            request.session.set_expiry(0)

        if user is not None:
            login(request, user)
            messages.success(request, "Login successful")
            return redirect('index')
        else:
            messages.error(request, "Invalid username or password")
    else:
        for field, errors in form.errors.items():
            for error in errors:
                print(f"Error in field '{field}': {error}")
                messages.error(request, f"Error in field '{field}': {error}")

    return render(request, self.template_name, context)

Django 设置:

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.middleware.locale.LocaleMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",

]

ALLOWED_HOSTS = ["localhost"]

ALLOWED_CORS_HOSTS = ["http://localhost"]

CSRF_TRUSTED_ORIGINS = ['http://localhost:8000', "http://127.0.0.1"]

CSRF_COOKIE_SAMESITE = 'None'

CORS_ORIGIN_WHITELIST = (
    'http://localhost:8000',
)
django csrf
1个回答
0
投票

确保将 {% csrf_token %} 标签放置在表单的提交按钮之前。

            {% csrf_token %}

<button class="btn btn-primary d-grid w-100"> Sign up </button> 

© www.soinside.com 2019 - 2024. All rights reserved.