我正在做一个Django+React项目。我的React应用程序是我的only UI renderer (这意味着Django不提供模板或任何标记),而我的Django应用程序只用于serving APIs以访问我的数据库资源。
在特定的React页面上,我有login和test按钮,它们在Django后端向DRF API发送请求。
登录API视图
class AuthLogin(generics.GenericAPIView):
serializer_class = LoginSerializer
authentication_classes = [SessionAuthentication]
permission_classes = ()
def get(self, request):
user = request.user
if not user and not user.is_authenticated or user.is_anonymous:
return Response(
{
"status": True,
"message": "Login page accessed"
}, status=status.HTTP_200_OK
)
else:
return Response(
{
"status": False,
"message": "You are currently logged in"
}, status=status.HTTP_400_BAD_REQUEST
)
def post(self, request, *args, **kwargs):
res = []
res_stat = status.HTTP_401_UNAUTHORIZED
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=False)
validated_data = serializer.validated_data
if validated_data:
user = dj_auth(username=request.data.get('username'),
password=request.data.get('password'))
if user and user.is_authenticated and not user.is_anonymous:
auth_login(request, user)
res_stat = status.HTTP_200_OK
res = {
"status": True,
"message": "Login successful!",
"login": {
"date_time": timezone.now(),
"user": {
'id': user.id,
'first_name': user.first_name,
'last_name': user.last_name,
'email': user.email,
}
}
}
else:
res_stat = status.HTTP_401_UNAUTHORIZED
res = {
"status": False,
"message": "Invalid username and/or password"
}
else:
res_stat = status.HTTP_401_UNAUTHORIZED
res = {
"status": False,
"message": "Invalid username and/or password"
}
return Response(res, status=res_stat)测试API视图
class Test(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
if request.user and request.user.is_authenticated and not request.user.is_anonymous:
return Response({
"test": "coolsss",
"user": request.user.id
}, status=status.HTTP_200_OK)
else:
return Response({
"error": "Mind to login first?"
}, status=status.HTTP_401_UNAUTHORIZED)到目前为止,在上述API上的Django+React集成方面还不错。但是,我注意到了一个安全问题,我不完全确定如何从这一点出发。
我在一个隐秘的浏览器窗口里做了测试。但是,我也在Postman中测试了它。我注意到,在使用相同的csrftoken和sessionid cookie对邮递员进行测试之前,我已经关闭了我的匿名浏览器。当我关闭浏览器时,我假设会话被销毁了,因为它是隐藏的。
现在,当我在Postman中运行相同的程序时,test端点仍然进行身份验证,识别用户,并返回正响应。我不知道这是否应该发生,应该用什么方法来解决这个问题。
我看到的一个示例场景是,假设Kate登录并离开她的工作站一分钟,这将是一场噩梦。她的同事John偷偷地进入她的浏览器,偷走了她当前会话的csrftoken和sessionid cookie值。
凯特回来了,不知什么原因关闭了她的浏览器。约翰在自己的电脑上使用邮递员,他向一个API发出了一些帖子请求,凯特被授权使用他偷来的令牌和会话is访问该API。
针对session/cookie-based身份验证中的这个问题,我正在考虑实现token-based身份验证,即使login视图更适合由服务器会话和csrftoken进行身份验证。
但是,如果我使用基于令牌的方法,我也会将该令牌存储在本地存储中,因此React将知道用户仍在登录并将该令牌用于后续请求。但是,一个极客总是可以使用dev工具并潜入本地存储中的令牌值。
在保持用户登录状态的前端的同时,我很难在后端正确地实现身份验证和安全性。
发布于 2020-07-03 10:16:06
基于令牌的(例如JWT)是将服务器端服务集成到客户端应用程序的“转到”选项。至于您所面临的问题,最简单的选择是在令牌中添加一个过期选项,这个选项可能仍然不是所有场景的解决方案。
事实上,当您创建一个客户端应用程序时,客户端拥有控制权,而您对此无能为力。保护令牌就像保护用户应该考虑的密码一样。你能做的最多的就是让其他人更难简单地拿出这个标记,然后在其他地方使用它。
您可以使用客户端必须生成的不同规格的多个令牌,如果它们都匹配,则可以为请求提供服务。但同样,这只会使其他人更难重复请求,而不是不可能的。
如果它是一个很难分解的编译应用程序,并且结合了一些方法,比如使用一些也安全地存储在客户端系统中的证书文件,那么您可以更加确定请求的安全性,但是JS太简单,无法读取和复制。
https://stackoverflow.com/questions/62712441
复制相似问题