Django Rest API同时使用Token与AllAuth社交认证的问题排查
解决方案:同时支持Token认证与社交JWT认证
问题根源
你开启了REST_USE_JWT=True,这意味着dj-rest-auth的社交登录接口返回的是JWT Token,但你的DRF配置中没有添加JWT认证类,导致DRF无法识别Authorization: Bearer <token>格式的请求头,进而无法完成认证。同时你需要保留原有的TokenAuthentication,所以需要同时配置两种认证方式。
步骤1:安装JWT依赖
dj-rest-auth依赖djangorestframework-simplejwt实现JWT功能,确保已安装:
pip install djangorestframework-simplejwt
步骤2:更新DRF认证配置
修改settings.py中的REST_FRAMEWORK配置,添加JWT认证类,同时保留TokenAuthentication:
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS':'rest_framework.schemas.coreapi.AutoSchema', 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', # 添加JWT认证类,用于处理社交登录返回的Bearer Token 'rest_framework_simplejwt.authentication.JWTAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), }
步骤3:配置JWT与dj-rest-auth关联
在settings.py末尾添加JWT的基础配置(可根据需求调整),并确保dj-rest-auth使用JWT序列化器:
# JWT配置示例 from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2), 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, } # 配置dj-rest-auth使用JWT序列化器 REST_AUTH_SERIALIZERS = { "LOGIN_SERIALIZER": "api.serializers.CustomLoginSerializer", "JWT_SERIALIZER": "dj_rest_auth.serializers.JWTSerializer", "JWT_TOKEN_CLAIMS_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", } REST_AUTH_TOKEN_MODEL = None # 禁用默认的Token模型,避免冲突(可选,如果你只想用JWT)
步骤4:验证两种认证方式
Token认证(原有方式):
- 调用
/auth/login/接口获取Token,请求头使用Authorization: Token <your-token>,依然可以正常访问受保护接口。
- 调用
社交JWT认证:
- 调用
/auth/google/或/auth/facebook/接口,会返回access_token和refresh_token(JWT格式)。 - 后续请求受保护接口时,使用请求头
Authorization: Bearer <access_token>,DRF会通过JWTAuthentication识别并完成认证。
- 调用
额外注意事项
- 你的自定义User模型
api.Users需确保继承自AbstractUser或正确配置了allauth所需的字段(如email),否则社交登录可能无法正确关联用户。 - 如果你希望社交登录后同时返回DRF的Token(而非仅JWT),可以自定义社交登录的序列化器,在登录成功后为用户生成并返回Token。示例如下:
这样前端可以选择使用JWT或DRF Token进行认证。# 在你的视图文件中 from dj_rest_auth.registration.views import SocialLoginView from rest_framework.authtoken.models import Token from dj_rest_auth.serializers import JWTSerializer class CustomSocialLoginSerializer(JWTSerializer): def get_token(self, user): # 生成或获取DRF Token token, _ = Token.objects.get_or_create(user=user) # 返回JWT和DRF Token return { 'access_token': self.context['request'].data.get('access_token'), 'refresh_token': self.context['request'].data.get('refresh_token'), 'drf_token': token.key } class GoogleLogin(SocialLoginView): adapter_class = GoogleOAuth2Adapter client_class = OAuth2Client serializer_class = CustomSocialLoginSerializer
内容的提问来源于stack exchange,提问作者Gati
相关产品推荐
相关产品推荐

