使用social-app-django时遇AsgiRequest无session属性错误求助
解决 'AsgiRequest' object has no attribute 'session' 谷歌认证错误
嘿,我之前也踩过这个坑——Channels 1.x 和 Django 2.x 搭配时,ASGI 请求并不会自动继承 Django 的 session 中间件能力,这就是你报错的核心原因。虽然你已经把 MIDDLEWARE_CLASSES 改成了 MIDDLEWARE,但那只对传统 WSGI 请求生效,Channels 处理 HTTP 请求走的是独立的 ASGI 流程,得单独适配 session 支持。
下面是具体的解决步骤:
1. 编写 ASGI 兼容的 Session 中间件
在你的项目目录下创建一个 middleware.py 文件,把 Django 的 SessionMiddleware 适配成 ASGI 可用的版本:
from django.contrib.sessions.middleware import SessionMiddleware from channels.sessions import CookieMiddleware class ASGISessionMiddleware(SessionMiddleware): def __init__(self, inner): self.inner = inner async def __call__(self, scope, receive, send): # 先通过 CookieMiddleware 获取 cookie 中的 session key cookie_middleware = CookieMiddleware(self.inner) scope, receive, send = await cookie_middleware(scope, receive, send) # 用 Django 的 SessionMiddleware 处理 session 并挂载到 scope 上 request = self.process_request(scope) scope['session'] = request.session # 继续传递请求 await self.inner(scope, receive, send)
2. 在 Channels 路由中配置这个中间件
修改你的 routing.py,确保所有 HTTP 请求(包括谷歌认证的路径)都经过这个自定义中间件:
from channels.routing import ProtocolTypeRouter, URLRouter from django.conf.urls import url, include from your_project.middleware import ASGISessionMiddleware application = ProtocolTypeRouter({ "http": ASGISessionMiddleware( URLRouter([ # 包含 social-auth 的路由 url(r'^social/', include('social_django.urls', namespace='social')), # 其他 HTTP 路由可以放在这里或者 include 你的主 urls.py url(r'', include('your_app.urls')), ]) ), # 如果有 WebSocket 路由,继续在这里配置 })
3. 确认基础配置没问题
再检查一遍你的 settings.py,确保以下中间件已经在 MIDDLEWARE 列表里:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', # 必须存在 'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 必须存在 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 其他自定义中间件... ]
这样配置之后,当你访问 /social/login/google-oauth2/ 时,ASGI 请求就会带上合法的 session 属性,social-app-django 就能正常处理谷歌认证流程了。
内容的提问来源于stack exchange,提问作者Diego Gallegos
相关产品推荐
相关产品推荐

