为什么 django rest framework 需要为每个请求提供 auth token
why django rest framework wants auth token for every request
我刚开始使用 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
view
登录的令牌认证
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
其他都是默认的。
test_api 要求身份验证凭据,因为您在 settings.py.
中定义了默认权限 类
REST_FRAMEWORK = {
...
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
...
}
如果未指定,它会自动应用于所有视图。因此,您可以像这样在 settings.py 中将 DEFAULT_PERMISSION_CLASSES 设为空白:
'DEFAULT_PERMISSION_CLASSES': [],
或
您可以为所有视图函数显式定义 permission_classes。您可以使用
@permission_classes(())
我刚开始使用 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
view
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
其他都是默认的。
test_api 要求身份验证凭据,因为您在 settings.py.
中定义了默认权限 类REST_FRAMEWORK = {
...
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
...
}
如果未指定,它会自动应用于所有视图。因此,您可以像这样在 settings.py 中将 DEFAULT_PERMISSION_CLASSES 设为空白:
'DEFAULT_PERMISSION_CLASSES': [],
或
您可以为所有视图函数显式定义 permission_classes。您可以使用
@permission_classes(())