首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django+React:如何正确实现API请求的身份验证和安全性?

Django+React:如何正确实现API请求的身份验证和安全性?
EN

Stack Overflow用户
提问于 2020-07-03 09:25:35
回答 1查看 635关注 0票数 0

我正在做一个Django+React项目。我的React应用程序是我的only UI renderer (这意味着Django不提供模板或任何标记),而我的Django应用程序只用于serving APIs以访问我的数据库资源。

在特定的React页面上,我有logintest按钮,它们在Django后端向DRF API发送请求。

登录API视图

代码语言:javascript
复制
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视图

代码语言:javascript
复制
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中测试了它。我注意到,在使用相同的csrftokensessionid cookie对邮递员进行测试之前,我已经关闭了我的匿名浏览器。当我关闭浏览器时,我假设会话被销毁了,因为它是隐藏的。

现在,当我在Postman中运行相同的程序时,test端点仍然进行身份验证,识别用户,并返回正响应。我不知道这是否应该发生,应该用什么方法来解决这个问题。

我看到的一个示例场景是,假设Kate登录并离开她的工作站一分钟,这将是一场噩梦。她的同事John偷偷地进入她的浏览器,偷走了她当前会话的csrftokensessionid cookie值。

凯特回来了,不知什么原因关闭了她的浏览器。约翰在自己的电脑上使用邮递员,他向一个API发出了一些帖子请求,凯特被授权使用他偷来的令牌和会话is访问该API。

针对session/cookie-based身份验证中的这个问题,我正在考虑实现token-based身份验证,即使login视图更适合由服务器会话和csrftoken进行身份验证。

但是,如果我使用基于令牌的方法,我也会将该令牌存储在本地存储中,因此React将知道用户仍在登录并将该令牌用于后续请求。但是,一个极客总是可以使用dev工具并潜入本地存储中的令牌值。

在保持用户登录状态的前端的同时,我很难在后端正确地实现身份验证和安全性。

EN

回答 1

Stack Overflow用户

发布于 2020-07-03 10:16:06

基于令牌的(例如JWT)是将服务器端服务集成到客户端应用程序的“转到”选项。至于您所面临的问题,最简单的选择是在令牌中添加一个过期选项,这个选项可能仍然不是所有场景的解决方案。

事实上,当您创建一个客户端应用程序时,客户端拥有控制权,而您对此无能为力。保护令牌就像保护用户应该考虑的密码一样。你能做的最多的就是让其他人更难简单地拿出这个标记,然后在其他地方使用它。

您可以使用客户端必须生成的不同规格的多个令牌,如果它们都匹配,则可以为请求提供服务。但同样,这只会使其他人更难重复请求,而不是不可能的。

如果它是一个很难分解的编译应用程序,并且结合了一些方法,比如使用一些也安全地存储在客户端系统中的证书文件,那么您可以更加确定请求的安全性,但是JS太简单,无法读取和复制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62712441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档