Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork824
Description
Developing a dashboard using Django channels, two different consumers are implemented, UserConsumer and RequestConsumer.
In UserConsumer methods like login, logout and get_user are implemented. The user Authentication is being done using OTP code sent to user mobile so that a user_send_code method is in charge of sending SMS while the user_login method verifies the code sent by user. UserConsumer is implemented as follow:
class UserConsumer(AsyncJsonWebsocketConsumer): async def connect(self): await self.accept() async def receive_json(self, content=None, **kwargs): action = content.get("action", "user.get_user") if action == "user.login": await self.user_login(content) elif action == "user.send_code": await self.user_send_code(content) elif action == "user.logout": await self.user_logout() else: await self.user_get_user() async def user_send_code(self, content): await self.send("we will send sms to: {}".format(content['mobile'])) if check_mobile_pattern(content["mobile"]): code = random.randint(1111, 9999) self.scope[VERIFY_CODE] = code self.scope[MOBILE] = content["mobile"] result = await send_sms(content["mobile"], code) if result: await self.send_json(send_code(200)) else: await self.send_json(send_code(400)) else: await self.send_json(send_code(SystemErrorCodes.InvalidMobilePattern)) async def user_get_user(self): if self.scope['user'].is_authenticated: await self.send_json({"id": self.scope['user'].id}) else: await self.send_json(send_code(SystemMessageCodes.AnonymousUserMessage)) async def user_login(self, content): verify_code = self.scope.get("verify_code") code = content.get("code") mobile = self.scope.get(MOBILE) if mobile is not None and verify_code is not None and code == verify_code: user = await load_user_by_mobile(mobile) del self.scope[VERIFY_CODE] # login the user to this session. await login(self.scope, user) # save the session (if the session backend does not access the db you can use `sync_to_async`) await database_sync_to_async(self.scope["session"].save)() await self.send_json(send_code(200)) else: await self.send_json(send_code(SystemErrorCodes.InvalidVerifyCode))after sending the right code to web service, user logins and user_get_user method returns the userID. However when I try to open a new Socket of class RequestConsumer, the user is not set in the scope and socket closed. Here is the code:
class RequestConsumer(AsyncWebsocketConsumer): async def connect(self): self.user = self.scope['user'] if self.user.is_authenticated: await self.accept() else: await self.close()my asgi application is implemented as follow:application = ProtocolTypeRouter({ "http": django_asgi_app, "websocket": AllowedHostsOriginValidator( AuthMiddlewareStack( URLRouter( [ path("user/", UserConsumer.as_asgi()), path('requests/', RequestConsumer.as_asgi()), ] ) ) ),})so both consumer are using same AuthMiddlewareStack middleware. And here is some parts of my settings.py file:
INSTALLED_APPS = [ 'daphne', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'file_process.apps.FileProcessConfig', 'channels', 'users_app.apps.UsersAppConfig', 'requests_apps.apps.RequestsAppConfig']MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]SESSION_ENGINE = 'django.contrib.sessions.backends.db' # Default session storageSESSION_COOKIE_NAME = 'sessionid' # Default cookie nameSESSION_COOKIE_HTTPONLY = True # Prevent JavaScript accessSESSION_COOKIE_SECURE = False # Set to True if using HTTPSSESSION_EXPIRE_AT_BROWSER_CLOSE = FalseSESSION_SAVE_EVERY_REQUEST = Trueand finally this is a sample test script I've provided for the client side:
<script>const socket1 = new WebSocket("ws://localhost:8000/user/");socket1.onopen = () => { console.log("Login WebSocket Connected");};socket1.onerror = (error) => { console.error("WebSocket Error: ", error);};socket1.onclose = () => { console.log("Login WebSocket Closed");};socket1.onmessage = (event) => { const data = JSON.parse(event.data); console.log("Message from server: ", data); if (data.code === 200) { const socket2 = new WebSocket("ws://localhost:8000/requests/"); socket2.onopen = () => { console.log("Login WebSocket Connected"); }; socket2.onerror = (error) => { console.error("WebSocket Error: ", error); }; socket2.onclose = () => { console.log("Login WebSocket Closed"); }; } else { alert("Login Failed!"); }};document.getElementById("loginForm").addEventListener("submit", (e) => { e.preventDefault(); const code = document.getElementById("code").value; const message = { action: "user.login", code: code, }; socket1.send(JSON.stringify(message));});</script>I couldn't find any cookie being sent to my browser if there should be one there.
This is my first webservice developed bydjango-channels so I'm not sure if I have done everything properly.