【问题标题】:Django session on mobile applications移动应用程序上的 Django 会话
【发布时间】:2016-09-15 21:58:42
【问题描述】:

我们目前正在为我们的网站开发一个使用 Django 构建的移动应用程序(使用 ionic)。每次用户登录时,我们都会在站点上使用 django 会话。据我了解,django 会话会在客户端中设置会话 ID,该会话 ID 存储在浏览器的 cookie 中。如果移动应用与 django 分开,我们如何在移动应用中设置此会话 id?

【问题讨论】:

    标签: django session


    【解决方案1】:

    我看到至少三种方法可以解决这个问题:

    1. 找到一种方法让您的 ionic 应用与 django 的 cookie(会话和 CSRF)一起工作。
    2. 以三种方式更改您的 django 应用程序:1) 具有登录/注销视图,为移动应用程序提供身份验证令牌,2) 扩展 SessionMiddleware 以从通过“授权”HTTP 标头发送的身份验证令牌中提取会话 ID移动应用的请求,3) 扩展 django 的 CSRF 中间件,以使并非来自 Web 浏览器的请求免于 CSRF 检查。
    3. 尝试使用现有的解决方案向 Django 添加 JWT(Json Web Token)身份验证。

    让基于 WebView 的混合移动应用与 android 和 ios 上的 cookie 一起正常工作似乎并非易事(例如 Handling cookies in PhoneGap/Cordova)。

    到目前为止,我发现的 JWT-auth 的现有解决方案似乎没有使用 Django 的会话(我觉得这很方便,因为有一个统一的解决方案可以杀死手机/计算机被盗或被盗的用户的会话他们的帐户被黑了)。如果有人知道在 django 常规会话之上进行令牌身份验证的可插拔解决方案,请发表评论。

    详述方法二:

    • 当您的移动应用程序不处理 cookie 时,由于 Django 的 CSRF 检查,它甚至无法登录。这就是为什么来自您的移动应用的请求需要不受 CSRF 保护的原因。

    注意:只是禁用 CSRF 保护。虽然移动应用程序不易受到 CSRF 攻击,但访问现有网站的人的浏览器仍然存在。

    • 要扩展 CSRF 机制以免除非浏览器请求,您需要一种有效的方法来确定请求是否来自 Web 浏览器。我们可以查看一堆 HTTP 标头(例如,Referer、Cookie、X-Requested-With、Origin)来了解一下。现在让我们假设您的合法网站用户没有欺骗他们的标题。

    • 使用与 CSRF 豁免相同的“is-web-browser”检查来保护移动应用的登录/注销视图。

    示例代码(对于 Android 移动应用,来自移动应用的 iOS 标头可能不同):

    def is_mobile_app_access(request):
        return request.META.get('HTTP_REFERER', None) is None 
            and request.META.get('HTTP_COOKIE', None) is None 
            and request.META.get('HTTP_X_REQUESTED_WITH', None) == 'your.app.name.here' 
            and request.META.get('HTTP_ORIGIN', None) == 'file://'
    
    class CustomCsrfViewMiddleware(CsrfViewMiddleware):
        def process_view(self, request, callback, callback_args, callback_kwargs):
            if is_mobile_app_access(request):
                return None
            else:
                return super(CustomCsrfViewMiddleware, self).process_view(request, callback, callback_args, callback_kwargs)
    
        def process_response(self, request, response):
            if is_mobile_app_access(request):
                return response
            else:
                return super(CustomCsrfViewMiddleware, self).process_response(request, response)
    
    
    class CustomSessionMiddleware(SessionMiddleware):
        def process_request(self, request):
            if is_mobile_app_access(request):
                session_key = request.META.get("HTTP_AUTHORIZATION", None)
            else:
                session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
            request.session = self.SessionStore(session_key)
    

    如果有人发现这种方法存在根本问题,请告诉我。我想这种方法中最薄弱的环节是is_mobile_app_access 检查的可靠性。

    你最后做了什么?

    【讨论】:

    • 很好的答案@grumpi。我实现了使用令牌的第二种方法。我的应用程序也是 django(网络用户)和 django-rest(移动用户)的组合。我们的代码几乎相同。我还制作了一个自定义中间件,并检测请求是来自网络还是移动设备。我也发现第三种方法很棒,虽然我还没有使用它
    猜你喜欢
    • 1970-01-01
    • 2016-03-27
    • 2012-05-27
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多