关于移动应用程序的Django会议

use*_*296 5 django session

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

小智 6

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

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

让基于WebView的混合移动应用程序在android和ios上使用cookie正常工作似乎并非易事(例如在PhoneGap/Cordova中处理cookie).

到目前为止,我发现现有的JWT-auth解决方案似乎没有使用Django的会话(我觉得这样做非常方便,因为它有一个统一的解决方案来杀死那些让他们的手机/电脑被盗或他们的帐户遭到攻击的用户的会话).如果有人知道在django常规会话之上进行令牌认证的可插拔解决方案,请发表评论.

详细说明方法2:

  • 当您的移动应用程序无法处理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)
Run Code Online (Sandbox Code Playgroud)

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

你到底做了什么?