Django通过access_token注册时存储refresh_token等额外数据方案
OAuth字段存储与接口传参方案
一、refresh_token、过期时间等字段的存储方法
python-social-auth自带的UserSocialAuth表默认提供了extra_dataJSON字段,专门用来存储OAuth流程返回的除用户基础信息外的所有token相关字段,不需要额外修改数据表结构,只要调整传参逻辑就能自动完成存储:
do_auth()方法本身支持接收完整的token响应字典作为入参,不是只能传入单个access_token字符串。你把next-auth返回的包含access_token、refresh_token、expires、token_type、scope的完整token对象传入,框架在完成用户匹配/创建流程时,会自动把这些字段写入对应用户社交账号记录的extra_data中。- 如果需要把特定字段单独存储到自定义模型字段,或者做字段值的自定义加工,新增一个pipeline函数加入社交登录流程即可,示例代码:
# 加入settings中SOCIAL_AUTH_PIPELINE配置的用户创建步骤之后 def save_custom_oauth_fields(backend, user, response, *args, **kwargs): social_account = user.social_auth.get(provider=backend.name) # 从OAuth返回结果中提取目标字段 refresh_token = response.get('refresh_token') expires = response.get('expires_at', response.get('expires')) # 自定义更新extra_data内容 social_account.extra_data.update({ 'refresh_token': refresh_token, 'expires': expires }) # 如果扩展了UserSocialAuth模型加了独立字段,直接赋值保存即可 # social_account.refresh_token = refresh_token # social_account.expires_at = expires social_account.save()
二、接口传参标准格式
这个场景没有强制的统一传参规范,结合python-social-auth的入参规则和前后端分离实践,核心要求只有一个:传入do_auth()的参数,要么是单个access_token字符串,要么是包含access_token键的完整token字典,其他字段按需携带即可。
多字段场景推荐用POST请求传JSON参数,比GET传参更安全、支持更复杂的结构:
- 请求头设置
Content-Type: application/json - 请求体格式参考:
{ "access_token": "next-auth返回的access_token值", "refresh_token": "next-auth返回的refresh_token值", "expires_in": 3599, "expires_at": 1718000000, "token_type": "Bearer", "scope": "openid email profile" }
对应修改原有视图逻辑,兼容完整参数传入:
import json from django.http import HttpResponse, JsonResponse from social_django.utils import psa @psa('social:complete') def register_by_access_token(request, backend): # 优先读取POST JSON格式的完整token参数 if request.method == "POST": try: token_params = json.loads(request.body) except json.JSONDecodeError: return JsonResponse({"error": "非法参数格式"}, status=400) else: # 兼容原有GET方式传单个access_token的逻辑 token_params = request.GET.get("access_token") if not token_params: return JsonResponse({"error": "缺少access_token参数"}, status=400) # 直接传入完整参数字典,框架会自动解析存储所有token字段 user = request.backend.do_auth(token_params) if user: return JsonResponse(get_tokens_for_user(user)) return HttpResponse("Unauthorized", status=401)
- 注意事项:传字典参数时必须保证
access_token键存在,否则框架会抛出参数错误;字段名尽量和OAuth标准返回字段保持一致,避免框架无法自动识别过期时间、refresh_token等字段。
内容的提问来源于stack exchange,提问作者Viraj
相关产品推荐
相关产品推荐

