【问题标题】:why django rest framework wants auth token for every request为什么 django rest 框架需要为每个请求提供身份验证令牌
【发布时间】:2021-01-26 13:44:14
【问题描述】:

我刚开始使用 django rest 框架。我测试了一个单一的视图功能,它工作。

@api_view(['GET', ])
def test_api(request):
    if request.method == 'GET':
        data = {}
        data['response'] = 'Test!'
        return Response(data=data)

在那之后我测试了注册视图并且它也可以工作。

@api_view(['POST', ])
def doctor_registration_view(request):

    if request.method == 'POST':
        serializer = DoctorRegistrationSerializer(data=request.data)
        data = {}
        if serializer.is_valid():
            doctor = serializer.save()
            data['response'] = 'successfully registered.'
            data['email'] = doctor.user.email
            data['first_name'] = doctor.user.first_name
            data['last_name'] = doctor.user.last_name
            data['phone_number'] = doctor.user.phone_number
            data['social_id'] = doctor.user.social_id
            data['mc_code'] = doctor.mc_code
            token = Token.objects.get(user=doctor.user).key
            data['token'] = token
        else:
            data = serializer.errors
        return Response(data)
class RegistrationSerializer(serializers.ModelSerializer):

    password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name', 'phone_number', 'social_id', 'password', 'password2']
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def save(self):
        user = User(
            email=self.validated_data['email'],
            first_name = self.validated_data['first_name'],
            last_name=self.validated_data['last_name'],
            phone_number=self.validated_data['phone_number'],
            social_id=self.validated_data['social_id'],
        )
        password = self.validated_data['password']
        password2 = self.validated_data['password2']

        if password != password2:
            raise serializers.ValidationError({'password': 'Passwords do not match.'})

        user.set_password(password)
        user.save()
        return user

在此之后,我测试了使用obtain_auth_token 视图登录的令牌身份验证

urlpatterns = [
    path('test/', test_api, name='test-api'),
    path('register', registration_view, name='register'),
    path('login', obtain_auth_token, name='login'),
]

现在当我请求test_api 时,它会说

{"detail": "Authentication credentials were not provided."}

虽然我没有将@permission_classes((IsAuthenticated,)) 用于查看功能,但我不知道为什么test_api 需要身份验证令牌

setting.py:


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'users.apps.UsersConfig',
    'api.apps.ApiConfig',

    'rest_framework',
    'rest_framework.authtoken',
]


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}


MIDDLEWARE = [
    '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',
]

AUTH_USER_MODEL = 'users.User' # change the built-in user model

其他的都是默认的。

【问题讨论】:

  • 您是如何配置身份验证设置的...?
  • 你的DEFAULT_PERMISSION_CLASSES设置值是多少?
  • 请发布您的settings.py 文件 - 我想在尝试回答之前查看您的INSTALLED_APPSMIDDLEWARE_CLASSES。确保编辑任何秘密值:-)
  • 是的,所以您将默认授权设置设置为需要身份验证...
  • 哇。所以当我想要一个请求的身份验证令牌时,我应该只为那个视图添加@permission_classes((IsAuthenticated,))?而不是设置DEFAULT_PERMISSION_CLASSES??

标签: python django django-rest-framework django-rest-auth


【解决方案1】:

test_api 要求提供身份验证凭据,因为您在 settings.py 中定义了默认权限类。

REST_FRAMEWORK = {
...
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
...
}

如果没有指定,它会自动应用于所有视图。因此,您可以像这样在 settings.py 中将 DEFAULT_PERMISSION_CLASSES 设为空白:

'DEFAULT_PERMISSION_CLASSES': [],

您可以为所有视图函数显式定义权限类。您可以使用

@permission_classes(())

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2014-04-14
    • 2020-09-12
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多