python - django.contrib.auth.login() 函数不返回任何已登录的用户
问题描述
我使用 Django 的内置身份验证系统创建了一个基本应用程序。我成功地使用在 shell 中创建了一个用户对象
>>python manage.py createsuperuser
。
然后,我创建了一个基本视图“UserLogin”以及相应的序列化程序/url,以使用 django.contrib.auth authenticate() 和 login() 函数登录现有用户。在使用我创建的用户的凭据进行测试后,登录功能似乎已经成功运行。
为了测试这一点,我创建了另一个视图函数“CurrentUser”,它返回当前登录用户的用户名。但是,此视图将用户返回为空。
为什么“当前用户”视图不会返回已登录的用户?我在下面附上了我的代码(减去导入)。
视图.py:
class UserLogin(APIView):
def post(self, request, format = None):
serializer = UserLoginSerializer(data=request.data)
if serializer.is_valid():
user = authenticate(username=serializer.validated_data["username"], password=serializer.validated_data["password"])
if user is not None:
login(request, user)
return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
return Response("Invalid username/password", status=status.HTTP_401_UNAUTHORIZED)
return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
class CurrentUser(APIView):
def get(self, request, format = None):
return Response(self.request.user.username)
序列化程序.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username']
class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField(max_length=300, required=True)
password = serializers.CharField(required=True, write_only=True)
网址.py:
urlpatterns = [
path('login/', views.UserLogin.as_view()),
path('current/', views.CurrentUser.as_view())
]
任何指导将不胜感激。
谢谢
解决方案
您必须在 DRF 设置中将默认身份验证类设置为会话身份验证类。在此处阅读有关它的更多信息 [1]。
会话身份验证使用会话 ID 来识别用户。因此,您必须在请求中发送基于 cookie 的会话 ID。在此处阅读有关会话身份验证的信息 [2]。
例如:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication', # <-- set this class
]
}
使用此代码:
def post(self, request, format = None):
serializer = UserLoginSerializer(data=request.data)
if serializer.is_valid():
user = authenticate(username=serializer.validated_data["username"], password=serializer.validated_data["password"])
if user:
return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
return Response("Invalid username/password", status=status.HTTP_401_UNAUTHORIZED)
return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
但我的建议是使用 Token auth [3]。
要使用令牌身份验证 2,事情会发生变化:
- DRF 设置中的默认身份验证类
- 向任何 DRF API 视图发送请求时,您将 Auth 标头发送为
Token <token-value>
您的 post 方法和 API 视图代码将保持不变。
[1] https://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme
[2] https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication
[3] https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
推荐阅读
- python - AppStartError: 无法创建进程 "C:/Program Files (x86)/PokerSnowie/PokerSnowie.exe" CreateProcess 返回的错误:
- azure-pipelines - 如何停止从 Azure 中的 TFVC 存储库签出开发服务器管道?
- javascript - 在 parseFloat() 之后添加小数位的最快方法,类似于 Python 的 float()
- python - dask.dataframe.read_csv 无法访问网络服务器上的文件
- spring-boot - VisualVm:cpu 图形面板显示“此 JVM 不支持”
- c - c 迭代时出错:使用未声明的标识符 i
- javascript - 我有 2 个 javascript 文件。如何将它们捆绑到一个文件中并将所有代码包含在一个封闭的范围内?
- php - 在 PHP 文件中将 cURL 与 Google Apps Script Web App 一起使用时遇到问题
- php - 如何使它选择