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

Angular无法获取Django返回的JWT令牌,请求出现403错误

问题分析与解决方案

你的核心问题是跨域场景下Cookie未正确传递导致403错误,以及Angular 17 SSR环境下localStorage的使用限制,以下是针对性解决步骤:


一、解决跨域Cookie未传递的403问题

1. 修正Django登录接口的Cookie设置

你的UserView依赖从Cookie获取jwt,但登录接口需确保Cookie配置支持跨域传递。修改登录视图(LoginView)的响应代码:

# LoginView中返回响应的部分
response = Response({'message': 'Login success'})
response.set_cookie(
    key='jwt',
    value=generated_token,  # 你的JWT生成结果
    httponly=True,  # 防XSS攻击,建议开启
    secure=False,  # 开发环境用False,生产HTTPS环境改为True
    samesite='Lax',  # 关键:跨域场景不能用Strict,生产HTTPS可设为None
    max_age=3600*24,  # Cookie有效期,按需调整
    path='/'  # 确保全站接口可访问该Cookie
)
return response

Postman能正常请求是因为它不严格遵循浏览器的SameSite规则,而浏览器会拦截SameSite=Strict的跨域Cookie。

2. 清理Django CORS配置冲突

你的settings.py中CORS_ORIGIN_WHITELIST与CORS_ORIGIN_ALLOW_ALL冲突,保留白名单更安全,同时补全中间件顺序:

# 移除 CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = [
    'http://localhost:4200',
]
CORS_ALLOW_CREDENTIALS = True

# 确保中间件顺序正确
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',  # 补全此中间件
    # 其他原有中间件...
]

3. 确保Angular所有请求携带Credentials

登录请求必须添加{withCredentials: true},否则浏览器不会存储服务器返回的Cookie:

// Angular登录请求示例
login(credentials: {username: string, password: string}) {
  this.http.post(
    'http://localhost:8000/api/login/', 
    credentials, 
    {withCredentials: true}  // 必须添加
  ).subscribe(res => {
    console.log('登录成功');
  });
}

你首页的请求已添加该配置,保持即可。


二、解决Angular 17中localStorage未定义的错误

Angular 17默认启用SSR(服务端渲染),服务端环境不存在浏览器专属的localStorage,需做环境判断:

import { Component, OnInit, PLATFORM_ID, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { isPlatformBrowser } from '@angular/common';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})
export class HomeComponent implements OnInit {
  message = '';

  constructor(
    private http: HttpClient,
    @Inject(PLATFORM_ID) private platformId: Object  // 注入平台标识
  ) {}

  ngOnInit(): void {
    // 仅在浏览器环境使用localStorage
    if (isPlatformBrowser(this.platformId)) {
      const token = localStorage.getItem('jwt');
      console.log(token);
    }

    this.http.get('http://localhost:8000/api/users/', {withCredentials: true}).subscribe(
      (res: any) => {
        this.message = `Hi ${res.name}`;
      },
      err => {
        this.message = 'You are not logged in';
      }
    );
  }
}

如果不需要SSR,可直接在angular.json中禁用:

// angular.json -> projects -> 你的项目 -> architect -> build -> options
"ssr": false

三、验证步骤

  1. 重启Django和Angular服务
  2. 登录后,打开浏览器开发者工具的Application -> Cookies -> http://localhost:8000,确认jwt Cookie存在
  3. 刷新首页,查看Django控制台的print(token)输出,应能正常获取令牌,403错误消失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:43:37