Django 会话导致 Angular 出现 JWT“令牌丢失或不正确”错误

Posted

技术标签:

【中文标题】Django 会话导致 Angular 出现 JWT“令牌丢失或不正确”错误【英文标题】:Django session causes angular with JWT "token missing or incorrect" error 【发布时间】:2017-05-20 13:33:50 【问题描述】:

设置

Angular 应用程序 (~1.5) 和 django 与 django (1.9.9) rest framework (3.5.3) 在服务器上运行,nginx 直接作为来自 / 的静态文件为客户端提供服务,并通过来自 /api 的 uwsgi 提供 api

djangorestframework-jwt 用于为客户端提供和验证 JWT 令牌。

重现错误:

    用户成功登录客户端前端(角度应用)。

    用户单击链接并从 api 获取一些数据。

    用户点击编辑数据,修改表单数据并PUT到api

    一切都好

    用户进入 /api 并通过 DRF 可浏览 API 使用相同的用户名和密码登录

    返回 / 并尝试再次使用 PUT 提交表单。

    Angular 从 django 服务器转发以下错误。

"data":"detail":"CSRF Failed: CSRF token missing or incorrect.","status":403, JWT..., "statusText":"Forbidden"

寻找原因

试图缩小问题范围,我发现使用客户端应用程序登录后没有找到 csrf cookie 或会话 cookie。我正在使用 JWT 进行身份验证,因此它不需要任何会话。

JWT 令牌被保存到本地存储,而不是 cookie。

在登录到 django 处理的 /api 或 /administration 应用程序后,为该域设置 csrftoken cookie 和 session cookie。

如果我删除 csrf cookie,角度应用程序仍然无法 PUT 或 POST。但如果我删除会话 cookie,它会再次开始正常工作。

问题

我应该如何设置 Django 和/或 Angular 应用程序,以便用户可以登录到任一应用程序而不会引起冲突?

我考虑过的事情

    如果用户根本不登录后端应用程序,对他们来说没有问题。但有些人会偶尔需要。

    如果我导致 Angular 删除会话 cookie,用户将从 Django 应用程序中注销,如果他们需要同时打开这两个应用程序,就会感到沮丧。

解决方案

在努力澄清这一点以写一篇 SO 帖子时,我找到了一个解决方案。本质上,更改 Django 设置以首先针对 JWT 进行身份验证,因此它永远不会尝试检查会话。

详情请见下文。

【问题讨论】:

【参考方案1】:

由于 Django 倾向于按照列出的顺序处理设置,因此我尝试将 JSONWebTokenAuthentication 行移动到列表的顶部,而不是像通常在遵循 REST framework JWT Auth 文档页面上的示例时那样的底部.

这成功了。因此,我没有放弃我几乎完成的问题,而是将其发布在这里以供您阅读。

REST_FRAMEWORK = 
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),

此错误的一个误导性特征是 csrf 令牌似乎不是实际问题。这是 angular 传回的会话令牌,因为 angular 是从与 API 相同的主机提供服务的。

【讨论】:

以上是关于Django 会话导致 Angular 出现 JWT“令牌丢失或不正确”错误的主要内容,如果未能解决你的问题,请参考以下文章

无法登录 Angular2 / Django 休息框架

当表单出现错误时,带有 angular.js 表单提交的 Django 不起作用

Django 迁移没有迁移 authtoken 和会话

Django模板:会话开始时删除按钮

用户没有属性会话-> Django

ng-deep 导致 Angular 中的 mat-select 出现问题