Session authentication with Django channels

后端 未结 3 544
心在旅途
心在旅途 2021-02-01 06:35

Trying to get authentication working with Django channels with a very simple websockets app that echoes back whatever the user sends over with a prefix \"You said: \"

3条回答
  •  情深已故
    2021-02-01 07:21

    I ran into this problem and I found that it was due to a couple of issues that might be the cause. I'm not suggesting this will solve your issue, but might give you some insight. Keep in mind I am using rest framework. First I was overriding the User model. Second when I defined the application variable in my root routing.py I didn't use my own AuthMiddleware. I was using the docs suggested AuthMiddlewareStack. So, per the Channels docs, I defined my own custom authentication middleware, which takes my JWT value from the cookies, authenticates it and assigns it to the scope["user"] like so:

    routing.py

    from channels.routing import ProtocolTypeRouter, URLRouter
    
    import app.routing
    from .middleware import JsonTokenAuthMiddleware
    
    application = ProtocolTypeRouter(
        {
            "websocket": JsonTokenAuthMiddleware(
                (URLRouter(app.routing.websocket_urlpatterns))
            )
        } 
    

    middleware.py

    from http import cookies
    from django.contrib.auth.models import AnonymousUser
    from django.db import close_old_connections
    from rest_framework.authtoken.models import Token
    from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
    
    class JsonWebTokenAuthenticationFromScope(BaseJSONWebTokenAuthentication):
    
        def get_jwt_value(self, scope):
            try:
                cookie = next(x for x in scope["headers"] if x[0].decode("utf-8") 
                    == "cookie")[1].decode("utf-8")
                return cookies.SimpleCookie(cookie)["JWT"].value
            except:
                return None
    
    
    class JsonTokenAuthMiddleware(BaseJSONWebTokenAuthentication):
        def __init__(self, inner):
            self.inner = inner
    
        def __call__(self, scope):
    
            try:
                close_old_connections()
                user, jwt_value = 
                    JsonWebTokenAuthenticationFromScope().authenticate(scope)
                scope["user"] = user
            except:
                scope["user"] = AnonymousUser()
            return self.inner(scope)
    

    Hope this helps this helps!

提交回复
热议问题