authentication - Django-Rest-Framwork 中的会话身份验证,这真的是我必须做的才能使 CSRF 安全吗?
问题描述
首先,这段代码可以工作,只是感觉不像这么简单的东西那么干净。
背景:我正在尝试在 DRF 中创建一个自定义登录 API 端点,该端点将由 React 前端使用。看来您必须手动强制在 DRF 中发送 csrf,这就是我所做的。
我不想通过 Django 表单发送,因为它看起来不像 RESTful,但这是我能找到的唯一避免这种情况的方法。请让我知道这是否是干净的代码。
序列化程序.py
from rest_framework import serializers
from django.contrib.auth import get_user_model # If used custom user model
UserModel = get_user_model()
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
def create(self, validated_data):
user = UserModel.objects.create_user(
username=validated_data['username'],
password=validated_data['password'],
email=validated_data['email'],
)
return user
class Meta:
model = UserModel
# Tuple of serialized model fields (see link [2])
fields = ( "id", "username", 'email', "password", )
视图.py
from rest_framework import permissions
from django.contrib.auth import get_user_model # If used custom user model
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import UserSerializer
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
class CreateUserView(APIView):
model = get_user_model()
permission_classes = [
permissions.AllowAny # Or anon users can't register
]
serializer_class = UserSerializer
@method_decorator(ensure_csrf_cookie)
def get(self, request, format = None):
return Response(status=status.HTTP_200_OK)
@method_decorator(csrf_protect)
def post(self,request, format = None):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.create(serializer.validated_data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
解决方案
CSRF 由 Django 启用,而不是 DRF。正如指定的那样,CSRF 保护仅在登录时启动。
登录和注册操作不需要受到 CSRF 保护(因为在 CSRF 攻击场景中需要密码数据,并且无法猜测)。
同样根据 Django 规范,GET 操作/视图不受 CSRF 保护。但是,GET 操作不应更改应用程序的状态。如果不是这种情况,并且您可以在前面实施 CSRF 保护(这对于 REST 应用程序是可能的,但对于默认的 Django 应用程序是不可能的),您可以使用您的装饰器手动保护它。
这主要不是 DRF 问题,而是 Django 问题。
推荐阅读
- ios - iOS在更新`alpha`后设置`isHidden`
- c - 如何使用c中的指针计算矩阵的行列式?
- python - 为数据输入创建 GUI(Python?)
- unity3d - 从 Unity3D 运行代码时 Visual Studio Code 自动保存
- node.js - 在 knex.js 中创建迁移会引发错误
- java - 为运行 java 映像的 pod 启用 REST 通信
- android - 在视图模型之间共享数据
- laravel-5 - Laravel Bootstrap 错误无法在我的电脑上运行,但在另一台电脑上运行良好
- linux - 无法让 nginx 在我的公共 IP 上服务
- linux - 连接EC2实例的私钥