Django Rest Framework JWT 未提供身份验证凭据
Authentication credentials were not provided with Django Rest Framework JWT
我在使用 Typscript 前端的 Django 休息框架中使用 JWT 实现令牌身份验证时遇到问题。我得到
{detail: "Authentication credentials were not provided."}
通过 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()),
]
project/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/
如果我的后端设置不正确,这将无法工作。所以这一定是我的前端代码。
根据您的描述,可能是CORS问题。因为您可以通过 curl
命令访问您的 api 端点。但不是浏览器。
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
我检查了你的 Angular 打字稿代码,似乎没问题。我建议在你的 django 项目中遵循以下说明,看看它是如何进行的:
1) 通过 pip install django-cors-headers
命令为 pip 安装它。
2) 在 settings.py 文件中,将此应用添加到您已安装的应用中:
INSTALLED_APPS = (
...
'corsheaders',
...
)
3) 您还需要添加一个中间件 class 来监听响应:
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。
我在使用 Typscript 前端的 Django 休息框架中使用 JWT 实现令牌身份验证时遇到问题。我得到
{detail: "Authentication credentials were not provided."}
通过 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()),
]
project/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/
如果我的后端设置不正确,这将无法工作。所以这一定是我的前端代码。
根据您的描述,可能是CORS问题。因为您可以通过 curl
命令访问您的 api 端点。但不是浏览器。
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
我检查了你的 Angular 打字稿代码,似乎没问题。我建议在你的 django 项目中遵循以下说明,看看它是如何进行的:
1) 通过 pip install django-cors-headers
命令为 pip 安装它。
2) 在 settings.py 文件中,将此应用添加到您已安装的应用中:
INSTALLED_APPS = (
...
'corsheaders',
...
)
3) 您还需要添加一个中间件 class 来监听响应:
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。