You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+Angular登录用户POST请求返回403 Forbidden问题排查

Hey there, let's troubleshoot this 403 Forbidden issue together—this is a super common pain point when pairing DRF with Angular, so I’ve got some solid leads to check.

First, let’s break down what we know:

  • Unauthenticated POSTs (login/register) work fine, so those views are likely exempt from CSRF checks.
  • DRF’s browsable API works because it automatically handles the CSRF token in forms.
  • Your authenticated POSTs fail with 403, which points to Angular not sending the correct CSRF token header.

Let’s start with fixing your Angular XSRF configuration

You’re mixing Angular’s old HttpModule and new HttpClientModule, which is probably causing your CSRF setup to not work as expected. The CookieXSRFStrategy is part of the deprecated HttpModule, but you’re using HttpClient (the modern version), so we need to switch to the correct configuration:

  1. Update your AppModule:
    • Remove the HttpModule import entirely—you don’t need it alongside HttpClientModule.
    • Replace your old XSRF provider with HttpClientXsrfModule configured to match Django’s CSRF cookie and header names.

Here’s the adjusted code:

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
import { AlertComponent } from './_directives/alert.component';
import { ProfileComponent } from './profile/profile.component';
import { AuthGuardService } from './_guards/auth-guard.service';
import { AlertService } from './_services/alert.service';
import { AuthService } from './_services/auth.service';
import { UserService } from './_services/User.service';

@NgModule({
  declarations: [
    AppComponent,
    RegisterComponent,
    LoginComponent,
    AlertComponent,
    ProfileComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule,
    HttpClientModule,
    // Configure XSRF for Django's cookie/header names
    HttpClientXsrfModule.withOptions({
      cookieName: 'csrftoken',
      headerName: 'X-CSRFToken',
    })
  ],
  providers: [
    // Remove the old XSRFStrategy provider here
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. Ensure your HTTP requests let Angular auto-inject the CSRF header:
    Your HttpOptions sets the Content-Type (which you need for application/json), but make sure you’re not overriding or blocking Angular from adding the X-CSRFToken header automatically. The HttpClient will handle this as long as the HttpClientXsrfModule is configured correctly—you don’t need to manually add the header to your HttpOptions.

Next, check your Django configuration (especially if you’re using separate front/back-end ports)

If your Angular app runs on localhost:4200 and DRF on localhost:8000 (cross-origin), you need to update two settings in settings.py:

  1. Install and configure django-cors-headers:
    This lets your backend accept requests from your Angular origin.

    • Install it: pip install django-cors-headers
    • Add to INSTALLED_APPS and MIDDLEWARE:
      INSTALLED_APPS = [
          # ...
          'corsheaders',
      ]
      
      MIDDLEWARE = [
          'corsheaders.middleware.CorsMiddleware',  # Place this early in the list
          'django.middleware.common.CommonMiddleware',
          # ... rest of your middleware
      ]
      
    • Allow your Angular origin:
      CORS_ALLOWED_ORIGINS = [
          "http://localhost:4200",
      ]
      
  2. Trust your Angular origin for CSRF:
    Add your front-end URL to CSRF_TRUSTED_ORIGINS:

    CSRF_TRUSTED_ORIGINS = [
        "http://localhost:4200",
    ]
    

Verify the token is being sent (using browser dev tools)

Open your browser’s DevTools > Network tab, then send the failing POST request. Check:

  • Cookies: Under the Application tab, confirm there’s a csrftoken cookie present.
  • Request Headers: Look for X-CSRFToken in the request headers—its value should match the csrftoken cookie.

If the cookie exists but the header isn’t sent, double-check your Angular HttpClientXsrfModule configuration. If the cookie doesn’t exist, ensure your Django template includes {% csrf_token %} (you have this in your code, which is good) or that you’re hitting a DRF endpoint that sets the CSRF cookie (like a simple GET endpoint) before sending authenticated POSTs.

One last check: DRF view CSRF exemptions

Make sure your authenticated views don’t have @csrf_exempt (they shouldn’t, since you want CSRF protection), and that your unauthenticated views (login/register) do have @csrf_exempt or use DRF’s AllowAny permission with CSRF exemption if needed.


内容的提问来源于stack exchange,提问作者Marcus Grass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:56:21