【问题标题】:Django Channels session is not persistent. disconnect -> logged outDjango Channels 会话不是持久的。断开连接 -> 注销
【发布时间】:2020-06-16 11:22:35
【问题描述】:

我有一个 websocket 路由器:

application = ProtocolTypeRouter({
    'websocket': 
    AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                [
                    url("ws/", Consumer)
                ]
            )
        )
    )
})

我通过向 websocket 发送命令来登录用户。用户登录如下:

if cmd == 'login':
    user = await database_sync_to_async(authenticate)(consumer.scope, email=request['eMail'], password=request['pass'])
    if user is not None:
        # login the user to this session.
        await login(consumer.scope, user, backend='allauth.account.auth_backends.AuthenticationBackend')
        # save the session
        consumer.scope['session'].modified = True
        await database_sync_to_async(consumer.scope['session'].save)()

每次,websocket 连接断开,用户不再登录。 我想,会话被保存了

consumer.scope['session'].save()

但它不起作用。会话不是持久的。

我该如何解决这个问题?

【问题讨论】:

    标签: django django-allauth django-channels django-sessions django-login


    【解决方案1】:

    您在 Django 中使用的是哪个会话后端。

    由于网络套接字在创建连接后如何工作,因此您无法设置任何 cookie,因此如果您使用依赖于 cookie 存储的会话后端,save 将无效,因为网络浏览器不能更新了。

    目前频道甚至不支持在接受方法期间设置 cookie。 https://github.com/django/channels/issues/1096#issuecomment-619590028

    但是,如果您确保您的用户已经拥有会话 cookie,那么您可以 upgrade 将该会话发送给已登录的用户。

    【讨论】:

    • 谢谢!是的,我想这就是原因。我使用了 Django 的常规后端。所以我现在的解决方案是我创建 JWT(Json Web Tokens)并将它们保存在浏览器的 localStorage 中。这样,我可以在连接到 websocket 时登录。
    • @matthaus-woolard 在您的回答中,您的意思是“在accept 方法中执行此操作”还是“在accept 方法之前执行此操作”?
    • @DanSwain yer...理论上应该可以在accept 方法中做到这一点,但是我只是仔细检查了一下,似乎 Django Channels 甚至从那里也没有传播会话 cookie :(
    猜你喜欢
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 2012-05-10
    • 1970-01-01
    • 2015-06-02
    • 2014-09-20
    相关资源
    最近更新 更多