Django Rest Framework JWT 未提供身份验证凭据

Posted

技术标签:

【中文标题】Django Rest Framework JWT 未提供身份验证凭据【英文标题】:Authentication credentials were not provided with Django Rest Framework JWT 【发布时间】:2019-02-19 19:38:50 【问题描述】:

我在带有 Typscript 前端的 Django REST 框架中使用 JWT 实现令牌身份验证时遇到问题。我来了

detail: "未提供身份验证凭据。"

通过 Typescript 调用我的 API,即:

  readonly BASE_URL = 'http://127.0.0.1:8000/'
  api_url = this.BASE_URL + 'items/'
  auth_url = this.BASE_URL + "api-token-auth/"

  getItemsService(token) 
    const headers = new HttpHeaders()
    headers.append('Content-Type', 'application/json')
    headers.append('Authorization', 'JWT ' + token.token)
    return this.http.get(this.api_url, headers: headers)
  

登录工作正常。当我尝试加载我遇到问题的项目时。

这是我的 Django 代码:

views.py

from rest_framework import generics
from .models import Item
from .serializers import ItemSerializer


class ItemList(generics.ListCreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer


class ItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

items/urls.py

from django.urls import path
from .views import ItemList, ItemDetail

urlpatterns = [
    path('', ItemList.as_view()),
    path('<int:pk>/', ItemDetail.as_view()),
]

项目/urls.py

from django.contrib import admin
from django.urls import include, path
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('items/', include('groceries.urls')),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),
    path('api-token-auth/', obtain_jwt_token),
]

settings.py

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

我认为问题必须与 Django 相关,但我能够得到我所期望的

curl -H "Authorization: JWT <token>" http://localhost:8000/items/

如果我的后端设置不正确,这将无法正常工作。所以它一定是我的前端代码。

【问题讨论】:

在 curl 中你使用了 Authorization 标头,但在 Angular Authentication 标头中 你不应该设置headers.append('Authorization', 'JWT ' + token.token)而不是身份验证吗? 你说的都对;但是,我在更正的标题中遇到了同样的错误。我已经编辑了我的问题以反映正确的标题 可能是 cors 问题***.com/a/49361474/1160794 【参考方案1】:

根据您的描述,这可能是 CORS 问题。因为您可以通过 curl 命令访问您的 api 端点。但不是用浏览器。

跨源资源共享 (CORS) 是一种机制,它使用额外的 HTTP 标头告诉浏览器让在一个源(域)运行的 Web 应用程序有权访问来自不同源的服务器的选定资源。当 Web 应用程序请求的资源与自己的来源不同(域、协议和端口)时,它会发出跨域 HTTP 请求。

我检查了您的 Angular 打字稿代码,看起来不错。我建议在您的 django 项目中遵循以下说明,看看它是如何进行的:

1) 通过pip install django-cors-headers 命令为 pip 安装它。

2) 在 settings.py 文件中,将此应用添加到您已安装的应用中:

INSTALLED_APPS = (
...
'corsheaders',
...
)

3) 您还需要添加一个中间件类来监听响应:

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]

记住 CorsMiddleware 应该放在尽可能高的位置。

4) 将此行添加到您的 settings.py 文件中。

CORS_ORIGIN_ALLOW_ALL = True

有关完整文档,请参阅django-cors-headers。

【讨论】:

还要确保这是一个 cors 问题,在请求 xhr 之前在浏览器上检查元素页面,并查看控制台日志。如果我们的猜测是正确的并且这是一个 CORS 问题,那么应该有一个类似 request blocked because of CORS ... 的日志或类似的东西......

以上是关于Django Rest Framework JWT 未提供身份验证凭据的主要内容,如果未能解决你的问题,请参考以下文章

DRF:如何将 django-rest-framework-jwt 集成到 Djoser

Django Rest Framework 中的 JWT 身份验证错误“无效签名”

Django Rest Framework JWT 身份验证测试

Django-Rest-Framework JWT 单元测试说“未提供身份验证”

Django Rest Framework 避免身份验证 JWT

如何让 django-rest-framework-jwt 在注册时返回令牌?