django - 缺少 Django CSRF 或需要 Sessions 中间件
问题描述
在尝试创建 django(2) rest framework api 时,我不断收到此错误。
Forbidden (CSRF token missing or incorrect.): /login/
在做了一些研究之后,问题可能出在我并不真正需要的会话身份验证上,因为我将回复基于令牌的身份验证。当我尝试从我的设置中删除一些会话身份验证时,我最终得到了这个。
AssertionError: The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware' before 'django.contrib.auth.middleware.AuthenticationMiddleware'.
Settings.py 片段
INSTALLED_APPS = [
# API (v1)
'apiV1.v1.accounts.apps.AccountsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Requirements
'corsheaders',
'rest_framework',
'rest_framework.authtoken',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'apiV1.urls'
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
),
}
视图.py
from django.contrib.auth import authenticate
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from apiV1.v1.accounts.models.user import User
from apiV1.v1.accounts.serializers.user import UserSerializerLogin
# login
class LoginView(APIView):
authentication_classes = ()
permission_classes = ()
@staticmethod
def post(request):
"""
Get user data and API token
"""
user = get_object_or_404(User, email=request.data.get('email'))
user = authenticate(username=user.email, password=request.data.get('password'))
if user:
serializer = UserSerializerLogin(user)
return Response(serializer.data)
return Response(status=status.HTTP_400_BAD_REQUEST)
解决方案
如果您不需要会话进行身份验证,则必须使用令牌身份验证。
这是视图的示例
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
class Login(ObtainAuthToken):
def post(self, request, *args, **kwargs):
"""
---
serializer: AuthTokenSerializer
"""
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'pk': user.pk,
'first_name': user.first_name,
'last_name': user.last_name,
})
或者您可以使用JWT
身份验证。
这里有一些对您有用的链接。
http://www.django-rest-framework.org/api-guide/authentication/
推荐阅读
- c# - 如何修复我的等待和重复代码?我无法单击重复操作的按钮
- c# - Rx .NET:ToTask vs LastAsync vs RunAsync
- spring-boot - kotlin抽象类在spring boot中反序列化
- python - RecursionError:使用线程时超出最大递归深度
- php - Laravel 中某个字段出现次数最多的查询
- unity3d - 为什么 unity2d 需要摄像头
- synology - Synology SSH CLI 上的递归权限失败
- android - 如何在phoneauth中从firebase中检索号码
- javascript - 如何从函数组件获取值到类组件(App.js)?
- java - 如何编写代码来提供数组的反转。我是java初学者