本地开发中Django与Angular跨端口共享Session/Cookie的方法
Hey there, this is such a common pain point when developing full-stack apps with separate frontend/backend ports—let's break down exactly how to get your session cookies playing nice across localhost:4200 and localhost:8000.
First, a quick recap: browsers treat different ports on the same domain as separate origins, so by default, cookies set by Django (on 8000) won't be sent to Angular's requests (to 8000) from 4200. We need to tweak both Django and Angular settings to bypass this.
Option 1: Configure CORS & Cookie Settings (Direct Cross-Port Requests)
This lets Angular hit Django's 8000 port directly while sharing cookies.
Step 1: Set Up Django for CORS & Shared Cookies
First, install the django-cors-headers package (it's the standard for handling CORS in Django):
pip install django-cors-headers
Now update your settings.py:
- Add it to
INSTALLED_APPS:INSTALLED_APPS = [ # ... other existing apps 'corsheaders', ] - Add its middleware early in the
MIDDLEWARElist (beforeCommonMiddleware):MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... other middleware entries ] - Configure allowed origins and cookie permissions:
# Allow your Angular dev server origin CORS_ALLOWED_ORIGINS = [ "http://localhost:4200", ] # Enable cookies in cross-origin requests CORS_ALLOW_CREDENTIALS = True # Make session cookies accessible across localhost ports SESSION_COOKIE_DOMAIN = "localhost" SESSION_COOKIE_SAMESITE = "Lax" # Use "None" if testing with HTTPS locally SESSION_COOKIE_SECURE = False # Only set to True in production (HTTPS) # Mirror settings for CSRF cookies (required for Django's protection) CSRF_COOKIE_DOMAIN = "localhost" CSRF_COOKIE_SAMESITE = "Lax" CSRF_COOKIE_SECURE = False
Step 2: Update Angular to Send Credentials
Every HTTP request from Angular to Django needs to include cookies. You can set this globally or per request:
Global Setup (Recommended)
In your app.module.ts, add an interceptor to enable credentials for all requests:
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; @Injectable() export class CredentialsInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { const clonedRequest = req.clone({ withCredentials: true }); return next.handle(clonedRequest); } } @NgModule({ imports: [HttpClientModule], providers: [ { provide: HTTP_INTERCEPTORS, useClass: CredentialsInterceptor, multi: true } ] }) export class AppModule { }
Per-Request Setup
If you only need credentials for specific requests:
this.http.get('http://localhost:8000/api/your-endpoint', { withCredentials: true }) .subscribe(response => { /* handle your response here */ });
Step 3: Handle CSRF Tokens (Critical for Django)
Django requires a CSRF token for POST/PUT/DELETE requests. Add another interceptor to fetch the token from cookies and attach it to request headers:
import { CookieService } from 'ngx-cookie-service'; // Install with `npm install ngx-cookie-service` import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; @Injectable() export class CsrfInterceptor implements HttpInterceptor { constructor(private cookieService: CookieService) {} intercept(req: HttpRequest<any>, next: HttpHandler) { if (req.method !== 'GET') { const csrfToken = this.cookieService.get('csrftoken'); const clonedRequest = req.clone({ headers: req.headers.set('X-CSRFToken', csrfToken) }); return next.handle(clonedRequest); } return next.handle(req); } }
Don't forget to add CookieService to your AppModule providers.
Option 2: Use Angular Proxy (Avoid Cross-Origin Entirely)
This is often simpler for local development—Angular's dev server proxies API requests to Django, making it look like both apps run on the same port.
Step 1: Create a Proxy Config File
Create proxy.conf.json in your Angular project root:
{ "/api/*": { "target": "http://localhost:8000", "secure": false, "changeOrigin": true, "pathRewrite": { "^/api": "" } } }
This forwards any request starting with /api to Django's 8000 port, stripping the /api prefix (adjust if your Django API uses a different base path).
Step 2: Update Angular Serve Command
Modify your package.json to use the proxy when starting the dev server:
"scripts": { "start": "ng serve --proxy-config proxy.conf.json" }
Step 3: Update Angular Requests
Now, request paths relative to Angular's port instead of Django's:
this.http.get('/api/your-endpoint') .subscribe(response => { /* handle your response here */ });
Since requests go to the same port (4200), cookies are shared automatically—no CORS settings or withCredentials needed!
Final Notes
- For production, since both apps run on port 80, you won't need these settings (just ensure Django's cookies are configured for your production domain).
- If using HTTPS locally (e.g.,
ng serve --ssl), setSESSION_COOKIE_SECUREandCSRF_COOKIE_SECUREtoTrue, andSESSION_COOKIE_SAMESITEto"None".
内容的提问来源于stack exchange,提问作者Jack

