You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django-rest-auth+Allauth集成Twitter登录报错Error 89:令牌无效或过期

解决Django Allauth+REST-Auth中Twitter登录返回"Invalid or expired token"的问题

你碰到的这个问题其实是Twitter OAuth1.0a和REST-Auth适配的典型坑——毕竟你之前搞定的FB、Google都是OAuth2,而Twitter至今还在用OAuth1,两者的认证流程差得挺多的。既然常规Twitter登录正常,那大概率是你漏了OAuth1相关的关键配置,或者自定义的重定向视图逻辑没踩对OAuth1的流程点。我给你梳理几个必查的方向:

1. 确认REST-Auth的Twitter适配器配置是否正确

Allauth的Twitter适配器默认是为Web登录设计的,REST-Auth需要额外适配OAuth1的令牌规则。先检查settings.py里的配置:

  • 确保用的是OAUTH1的密钥配置,不是OAUTH2:
SOCIALACCOUNT_PROVIDERS = {
    'twitter': {
        'OAUTH1_CLIENT_KEY': '你的Twitter API Key',
        'OAUTH1_CLIENT_SECRET': '你的Twitter API Secret',
    }
}
  • 确认开启了REST社交登录,并且URL配置包含Twitter登录端点:
REST_AUTH_SOCIAL_LOGIN_ENABLED = True

urlpatterns = [
    # ...其他业务URL
    path('rest-auth/twitter/', TwitterLogin.as_view(), name='twitter_login'),
]

2. 检查自定义重定向视图是否符合OAuth1的流程

Twitter的OAuth1需要两次请求交互:先获取请求令牌(request token)→ 跳转到Twitter授权 → 用授权后的验证码交换访问令牌(access token + token secret)。如果你直接让视图接收access_token和token_secret,等于跳过了请求令牌的验证步骤,Twitter自然会判定令牌无效。

正确的REST-Auth Twitter登录流程应该是:

  • 前端先GET请求/rest-auth/twitter/,获取Twitter授权的重定向URL(这一步由REST-Auth的TwitterLogin视图自动处理,它会向Twitter申请request token)
  • 前端跳转到该URL让用户授权,Twitter回调到Allauth默认的/accounts/twitter/login/callback/端点
  • 回调完成后,前端再POST请求/rest-auth/twitter/,传入回调返回的oauth_token和oauth_verifier(不是直接传access_token和token_secret)

如果你的自定义视图绕开了这个流程,建议先改用REST-Auth默认的TwitterLogin视图测试,看是否能正常工作。

3. 验证令牌相关的细节配置

错误码89常见的触发原因还有这些:

  • 混用了OAuth2令牌:Twitter的API分OAuth1和OAuth2两个版本,REST-Auth的Twitter适配器用的是OAuth1,别拿OAuth2的令牌过来用
  • 回调URL不匹配:检查Twitter开发者后台配置的"Callback URL",必须和Allauth里SOCIALACCOUNT_PROVIDERS['twitter']['CALLBACK_URL']完全一致,OAuth1对回调URL的匹配要求非常严格
  • 令牌签名错误:OAuth1要求请求必须签名,如果你手动生成令牌但没做正确签名,也会触发这个错误

4. 检查自定义适配器的逻辑(如果有)

如果你重载了Allauth的Twitter适配器,确保没篡改get_access_token方法的逻辑——这个方法负责和Twitter交换有效访问令牌,要是漏传了oauth_verifier这类关键参数,肯定会出问题。举个正确的自定义适配器示例:

from allauth.socialaccount.providers.twitter.provider import TwitterProvider
from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter

class CustomTwitterOAuthAdapter(TwitterOAuthAdapter):
    provider_id = TwitterProvider.id

    def get_access_token(self, request):
        # 尽量复用父类逻辑,不要随意修改
        return super().get_access_token(request)

最后一招:开启调试日志抓细节

在settings.py里开启Allauth的调试日志,能看到和Twitter交互的完整请求/响应内容,比只看错误码89有用得多:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {'class': 'logging.StreamHandler'},
    },
    'loggers': {
        'allauth': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

运行后看控制台输出,能精准定位是哪一步的请求出了问题。

优先排查流程问题,OAuth1的步骤比OAuth2繁琐很多,REST-Auth已经封装好了大部分逻辑,尽量不要自己手动处理令牌交换。

内容的提问来源于stack exchange,提问作者Tantel Sacubitri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:08:36