我有一个问题,我在 Django 中调用
login()
函数,尽管在请求会话中设置了用户 ID,但每当在另一个视图中我调用 request.user.is_authenticated
时,都会返回 True
。
我的登录视图:
class LoginView(APIView):
serializer_class = LoginUserSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
username = serializer.data.get('username')
password = serializer.data.get('password')
# If username is not present in the database at all
user_exist_query = User.objects.filter(username=username)
if not user_exist_query.exists():
return JsonResponse({"error": "Username does not exist"}, status = 401)
# If username and password match
user_auth_query = authenticate(username=username, password=password)
if user_auth_query is not None:
login(request, user_auth_query)
return JsonResponse({"message": "Login Successful"}, status = 200)
else:
return JsonResponse({"error": "Username and Password combination is incorrect"}, status = 401)
return JsonResponse({"error": "Bad Request"}, status=400)
身份验证实际起作用的另一种视图:
class CheckAuthView(APIView):
def get(self, request):
if request.user.is_authenticated:
return Response(status=status.HTTP_200_OK)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
我使用此视图来保护路由(使用 React 作为前端)。主页仅可供登录用户访问,每当我登录时,我都可以查看该页面,当我注销时,会显示不同的页面,因此证明在这里,获取
request.user
确实返回一个实际的用户。
存在问题的观点:
class CreateClubView(APIView):
serilizer_class = ClubSerializer
def post(self, request):
serializer = self.serilizer_class(data=request.data)
print(request.user.is_authenticated)
if serializer.is_valid():
clubName = serializer.data.get('name')
clubDesc = serializer.data.get('description')
clubLoc = serializer.data.get('location')
clubEmail = serializer.data.get('email')
clubContact = serializer.data.get('contact')
clubWebsite = serializer.data.get('website')
clubOrganizer = request.session['id']
queryset = Club.objects.filter(name=clubName)
if queryset.exists():
return Response(status=status.HTTP_400_BAD_REQUEST)
club = Club.objects.create(name=clubName, description=clubDesc, location=clubLoc,
email=clubEmail, contact=clubContact, website=clubWebsite, organizer=clubOrganizer)
club.save()
return Response(status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
打印
request.user
返回 AnonymousUser
并尝试访问 request.session['id']
会产生 KeyError。但情况不应该是这样,因为如果我提前登录(通过 API 调用登录的响应以及我可以访问主页的事实证明)。
此外,我进行 API 调用的 React 代码:
const response: Response = await fetch('http://127.0.0.1:8000/api/clubs/create', {
method: 'POST',
headers: headers,
body: JSON.stringify(form),
})
if (response.ok) {
console.log("Club created successfully");
navigate("/home");
} else {
console.log("Club creation failed");
}
我的代码有什么问题吗?我是否误解了 Django 会话的工作原理?我有另一个 Django 项目,我在其中做了同样的事情并且它在那里完美地工作。
我还尝试在通过执行
id
调用 login()
之前手动设置 request.session['id'] = User.objects.get(username=username).id
- 这也不起作用。
我看到了一些与 Django 相关的解决方案
settings.py
,我不相信我错过了任何东西?
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
'corsheaders.middleware.CorsMiddleware',
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
已修复,它实际上与 CORS 以及我如何调用 API 端点有关。登录后未设置会话 ID,因为我发出如下请求:
http://localhost:8000/api/authentication/login
将其更改为:
/api/authentication/login
,问题已解决,会话 ID cookie 已正确设置。