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

DRF集成python-social-auth时如何用simplejwt返回JWT

将python-social-auth令牌认证替换为djangorestframework-simplejwt JWT认证

现有实现

当前基于python-social-auth编写的OAuth令牌交换接口代码如下:

@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@psa()
def oauth_exchange_token_view(request, backend):
    serializer = SocialAccessTokenSerializer(data=request.data)
    if serializer.is_valid(raise_exception=True):
        # set up non-field errors key
        try:
            nfe = "non_field_errors"
        except AttributeError:
            nfe = 'non_field_errors'

        try:
            # 配合@psa装饰器,自动对接配置好的python-social-auth后端完成用户校验与拉取
            user = request.backend.do_auth(serializer.validated_data['access_token'])
        except HTTPError as e:
            # 向社交认证服务商发起请求出错,一般是传入的access_token格式错误或无效
            return Response(
                {'errors': {
                    'token': 'Invalid token',
                    'detail': str(e),
                }},
                status=status.HTTP_400_BAD_REQUEST,
            )

        if user:
            if user.is_active:
                # 原逻辑:生成静态永久Token
                token, _ = Token.objects.get_or_create(user=user)
                return Response({'access': token.key})
            else:
                return Response(
                    {'errors': {nfe: 'This user account is inactive'}},
                    status=status.HTTP_400_BAD_REQUEST,
                )
        else:
            return Response(
                {'errors': {nfe: "Authentication Failed"}},
                status=status.HTTP_400_BAD_REQUEST,
            )

原有逻辑在用户校验通过后,使用DRF内置的Token模型生成永久静态令牌返回:

token, _ = Token.objects.get_or_create(user=user)
return Response({'access': token.key})

需要将这部分逻辑替换为djangorestframework-simplejwt实现的JWT令牌生成逻辑。

改造方法

前置准备

  • 已安装djangorestframework-simplejwt依赖,且完成基础配置(在REST_FRAMEWORK配置项中指定JWT为默认认证类,按需配置令牌过期时间等参数)
  • 移除原有代码中对rest_framework.authtoken.models.Token的导入,新增JWT令牌类导入:
from rest_framework_simplejwt.tokens import RefreshToken

替换令牌生成逻辑

将原有生成静态Token的代码块,替换为JWT生成逻辑。djangorestframework-simplejwt提供了RefreshToken.for_user()方法,可以直接为已存在的用户对象签发配对的access访问令牌和refresh刷新令牌:

if user.is_active:
    # 为用户生成JWT令牌对
    refresh = RefreshToken.for_user(user)
    return Response({
        'access': str(refresh.access_token),
        'refresh': str(refresh)
    })

如果业务不需要返回刷新令牌,也可以仅返回access字段,但常规JWT鉴权场景建议同时返回两个令牌,配合刷新接口实现无感续期。

改造后完整视图代码

@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@psa()
def oauth_exchange_token_view(request, backend):
    serializer = SocialAccessTokenSerializer(data=request.data)
    if serializer.is_valid(raise_exception=True):
        try:
            nfe = "non_field_errors"
        except AttributeError:
            nfe = 'non_field_errors'

        try:
            user = request.backend.do_auth(serializer.validated_data['access_token'])
        except HTTPError as e:
            return Response(
                {'errors': {
                    'token': 'Invalid token',
                    'detail': str(e),
                }},
                status=status.HTTP_400_BAD_REQUEST,
            )

        if user:
            if user.is_active:
                refresh = RefreshToken.for_user(user)
                return Response({
                    'access': str(refresh.access_token),
                    'refresh': str(refresh)
                })
            else:
                return Response(
                    {'errors': {nfe: 'This user account is inactive'}},
                    status=status.HTTP_400_BAD_REQUEST,
                )
        else:
            return Response(
                {'errors': {nfe: "Authentication Failed"}},
                status=status.HTTP_400_BAD_REQUEST,
            )

注意:如果自定义了JWT的令牌载荷、序列化规则,RefreshToken.for_user()方法会自动适配你在simplejwt配置中定义的规则,不需要额外修改逻辑。

内容的提问来源于stack exchange,提问作者Paul Bénéteau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:12:21