Django-rest-auth+Allauth集成Twitter登录报错Error 89:令牌无效或过期
你碰到的这个问题其实是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

