I am developing a chatting app that allows social login. While developing all restapi functions, including social login functions, and developing chat customers using channel libraries, there was a problem with social login. This code is chatcustomer using websocketcunsumer.
enter code hereimport json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from .models import *
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
....
this is setting for channel
INSTALLED_APPS = [
'channels',
]
ASGI_APPLICATION = 'project.routing.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
routing.py in project root
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
asgi.py
import os
import django
from channels.routing import get_default_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()
application = get_default_application()
routing.py in chatapp
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w )/$', consumers.ChatConsumer.as_asgi()),
]
this is social login views.py
@api_view(['POST'])
def authenticate_kakao(request):
access_token = request.data["access_token"]
code =request.data['code']
"""
Email Request
"""
print("process1")
profile_request = requests.get(
"https://kapi.kakao.com/v2/user/me", headers={"Authorization": f"Bearer {access_token}"})
print("process2")
profile_json = profile_request.json()
kakao_account = profile_json.get('kakao_account')
email = kakao_account.get('email')
profile = kakao_account.get("profile")
nickname = profile.get("nickname")
profile_image = profile.get("profile_image_url")
print("process3")
"""
Signup or Signin Request
"""
try:
user = User.objects.get(email=email)
social_user = SocialAccount.objects.get(user=user)
if social_user is None:
return Response({'err_msg': 'email exists but not social user'}, status=status.HTTP_400_BAD_REQUEST)
if social_user.provider != 'kakao':
return Response({'err_msg': 'no matching social type'}, status=status.HTTP_400_BAD_REQUEST)
data = {'access_token': access_token, 'code': code}
accept = requests.post("http://localhost:8000/accounts/kakao/login/allauth/", data=data)
print("process5")
accept_status = accept.status_code
if accept_status != 200:
return Response({'err_msg': 'failed to signin'}, status=accept_status)
accept_json = accept.json()
#User model update
print("process6")
return Response(accept_json)
except User.DoesNotExist:
data = {'access_token': access_token, 'code': code}
accept = requests.post(
"http://localhost:8000/accounts/kakao/login/allauth/", data=data)
print("process7")
accept_status = accept.status_code
if accept_status != 200:
return Response({'err_msg': 'failed to signup'}, status=accept_status)
print("process8")
accept_json = accept.json()
#User model update
print("process9")
return Response(accept_json)
class KakaoLogin(SocialLoginView):
adapter_class = kakao_view.KakaoOAuth2Adapter
client_class = OAuth2Client
and urls.py
urlpatterns = [
path('kakao/authenticate/', login.authenticate_kakao),
path('kakao/login/allauth/', login.KakaoLogin.as_view()),
]
this is server log
$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
September 17, 2022 - 15:15:17
Django version 4.0.6, using settings 'project.settings.local'
Starting ASGI/Channels version 3.0.5 development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Forbidden: /dj-rest-auth/user/
HTTP GET /dj-rest-auth/user/ 403 [0.02, 127.0.0.1:49400]
process1
process2
process3
process4
there is a point that sends a request to 'kakao/login/allauth' inside of the function 'kakao/authenticate', and this is where the server stops. It seems strange to you, but it worked well until I applied the channel.
In my opinion, it became impossible for the server to process various requests by applying channel. but why? i don't understand this reason plz help me
CodePudding user response:
I think you are missing a few cases. I will give you a clear way of configuring WebSocket and HTTP apps. settings.py:
INSTALLED_APPS = [
'channels',
'rest_framework'
# and your other apps here
]
ROOT_URLCONF = 'project.urls'
WSGI_APPLICATION = 'project.wsgi.application'
ASGI_APPLICATION = "project.asgi.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
asgi.py:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
import django
django.setup()
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.security.websocket import AllowedHostsOriginValidator
import chat.routing
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AllowedHostsOriginValidator(AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
)),
})
chat/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w )/$', consumers.ChatConsumer.as_asgi()),
]
install uvicorn to run asgi application:
pip install uvicorn[standard]
run server command:
uvicorn project.asgi:application --reload
and it will work as expected.