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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:15:46