Discord OAuth2首次登录报'DiscordUser' object is not iterable错误如何解决
问题修复方案
错误根因
报错的核心原因是你自定义的DiscordAuthenticationBackend.authenticate方法返回值类型不统一:
- 首次登录时,对应用户还未在本地系统创建,方法直接返回了新建的单个
DiscordUser实例,该实例不可迭代,执行list(discord_user_auth)时自然抛出类型错误 - 登出后二次登录时,用户已存在于本地,方法返回的是可迭代的查询集对象,所以转列表后调用pop可以正常执行
修复方案
推荐方案(符合Django认证规范)
统一authenticate方法的返回值,不管是新创建的用户还是已存在的用户,都返回单个DiscordUser实例(这也是Django原生认证后端的标准返回格式),随后直接删除多余的类型转换逻辑即可,修改后的视图代码如下:
def discord_login_redirect(request, *args, **kwargs): code = request.GET.get("code") exchange_user = exchange_code(code) discord_user_auth = DiscordAuthenticationBackend.authenticate(request=request, user=exchange_user) login(request, discord_user_auth) return redirect("/app")
兼容方案(无需修改认证后端代码)
如果不方便调整认证后端的逻辑,可以在视图层增加类型判断做兼容:
def discord_login_redirect(request, *args, **kwargs): code = request.GET.get("code") exchange_user = exchange_code(code) discord_user_auth = DiscordAuthenticationBackend.authenticate(request=request, user=exchange_user) # 兼容不同返回类型 if not isinstance(discord_user_auth, DiscordUser): discord_user_auth = list(discord_user_auth).pop() login(request, discord_user_auth) return redirect("/app")
额外优化建议
你当前exchange_code方法中使用全局变量存储user和guilds,多用户并发请求时会出现数据混淆问题,建议移除全局变量,将这两个数据通过返回值传递,或者存入当前用户的session中。
内容的提问来源于stack exchange,提问作者PRA7H1K
相关产品推荐
相关产品推荐

