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

集成FusionAuth与Django-Rest-Framework:如何复用Access Token?

FusionAuth与Django-Rest-Framework + React集成:复用FusionAuth Token的实现方案

现有流程与问题

我目前正在把FusionAuth和Django-Rest-Framework(搭配React前端)集成,采用授权码授权流程:

  • React前端跳转到FusionAuth登录页,登录完成后携带authorization_code重定向回前端
  • 前端将该code传给Django后端,后端用它换取FusionAuth的access_token,再通过token拉取用户信息(含唯一ID)
  • 后端根据用户ID创建/获取本地Django用户,随后用knox生成本地token返回给前端做后续认证

现有伪代码如下:

from fusionauth.fusionauth_client import FusionAuthClient

client = FusionAuthClient(FA_API_KEY, FA_URL)

def authenticate(request):
  authorization_code = request.data["code"]
  fa_token_response = client.exchange_o_auth_code_for_access_token()
  fa_user_response = client.retrieve_user(user_id=fa_token_response["userId"])
  user, created = UserModel.objects.get_or_create(
      fa_id=fa_token_response["userId"],
      defaults={
        "username": fa_user_response["username"],
        "email": fa_user_response["email"],
      },
  )

  token = generate_token(user)  # 想替换成直接用FusionAuth的token

  return Response(
    {
      "token": token,
      "user_id": user.id,
    },
    status=status.HTTP_200_OK,
  )

现在想直接复用FusionAuth提供的access_token和refresh_token,以此共享过期时间、简化流程,但不清楚具体实现方式:

  • 是否可以直接复用FusionAuth的token?
  • 若每次请求都验证token,会不会存在效率问题?
  • 有没有现成的第三方库可以解决这个问题?

解决方案建议

1. 直接复用FusionAuth的Token

完全可以直接把FusionAuth返回的access_token、refresh_token以及过期时间一起返回给前端,前端后续请求时将access_token放在请求头(如Authorization: Bearer {token})中传给DRF后端即可。

2. 实现DRF认证后端验证Token

需要编写自定义的DRF认证后端,每次请求时验证FusionAuth的access_token有效性:

  • 核心逻辑是调用FusionAuth的introspect token API(若FusionAuth Token为JWT格式,也可直接本地验证)
  • 关于效率问题:可通过缓存验证结果解决,比如用Redis缓存已验证的有效Token,缓存过期时间与FusionAuth Token的过期时间一致,避免每次请求都调用FusionAuth API

示例认证后端伪代码:

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from fusionauth.fusionauth_client import FusionAuthClient
from django.core.cache import cache

client = FusionAuthClient(FA_API_KEY, FA_URL)

class FusionAuthTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return None
        
        token = auth_header.split(' ')[1]
        # 优先查询缓存
        cached_user_id = cache.get(f'fa_token_{token}')
        if cached_user_id:
            try:
                user = UserModel.objects.get(fa_id=cached_user_id)
                return (user, None)
            except UserModel.DoesNotExist:
                raise AuthenticationFailed('用户不存在')
        
        # 缓存未命中,调用FusionAuth验证Token
        response = client.introspect_o_auth_token(token)
        if not response.was_successful():
            raise AuthenticationFailed('Token无效或已过期')
        
        fa_user_id = response.success_response['userId']
        # 缓存验证结果,提前60秒过期避免时间差问题
        cache.set(f'fa_token_{token}', fa_user_id, timeout=response.success_response['expires_in'] - 60)
        
        user, _ = UserModel.objects.get_or_create(fa_id=fa_user_id)
        return (user, None)

随后在DRF配置中启用该认证后端:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'your_app.authentication.FusionAuthTokenAuthentication',
        # 其他认证方式...
    ]
}

3. 第三方库参考

  • 若需要简化OAuth2认证流程,可尝试django-oauth-toolkit,适配FusionAuth配置后可快速实现Token验证逻辑
  • 若FusionAuth使用JWT格式的Token,推荐用djangorestframework-simplejwt做本地验证,无需每次调用FusionAuth API,效率更高

内容的提问来源于stack exchange,提问作者trubliphone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:42:48