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

Django如何识别第一方应用访问?API权限方案咨询

Django API多认证方案优化:自身应用与第三方客户端权限区分

场景梳理

你的Django应用现状:

  • 自身前端基于模板,用JS fetch调用API,依赖allauth的Django内置会话认证,不用dj-rest-auth
  • Discord机器人作为第三方,用dj-rest-auth的Authorization: Bearer令牌认证
  • 现在要给其他第三方客户端加Authorization: Api-Key认证,同时得让自身应用正常访问API,还要实现差异化权限和限流

先分析你想到的两个方案,再给你更稳妥的优化思路:

方案1:中间件自动插入API Key

思路

写个中间件,识别自身应用的请求(比如通过IP、请求头),自动把合法的API Key塞进请求头,让自身请求走API Key认证逻辑。

优缺点

  • 优点:不用改前端和视图代码,逻辑简单粗暴
  • 缺点:
    • 中间件层面篡改请求头,后期排查认证问题时容易绕晕
    • 自身请求的识别逻辑如果不严谨,很容易被伪造请求绕过
    • 自身和第三方共用一套API Key机制,后续想给第三方单独做限流、加特殊权限会非常受限

方案2:自定义IsUsingFirstPartyApp权限类 + 逻辑或校验

思路

自定义权限类,通过HTTP_ORIGIN/HTTP_REFERER判断请求来自自身站点,然后在视图的permission_classes里用IsUsingFirstPartyApp | HasAPIKey(DRF支持逻辑或权限),满足任一条件就能访问。

优缺点

  • 优点:权限逻辑清晰,自身和第三方的认证方式明确分开,方便后续拆分权限和限流规则
  • 缺点:
    • ORIGIN/REFERER头是可以伪造的,单纯靠这俩判断有安全风险
    • 如果有内部后台任务调用API(比如Celery),这类请求没有浏览器头,会被拦截

推荐方案:多维度校验的自定义权限 + 分组配置

针对方案2的安全短板,强化校验维度,同时保留灵活的权限配置:

1. 强化IsFirstPartyApp权限类的安全性

不要只依赖请求头,结合会话Cookie、可信IP、自定义内部头多维度校验,大幅降低伪造风险:

from rest_framework.permissions import BasePermission
from django.contrib.sessions.models import Session
from django.utils import timezone
from ipaddress import ip_address, ip_network
from django.conf import settings

class IsFirstPartyApp(BasePermission):
    def has_permission(self, request, view):
        # 校验1:是否携带有效的Django会话Cookie(自身登录用户的请求会自动带)
        session_cookie = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        if session_cookie:
            try:
                session = Session.objects.get(session_key=session_cookie)
                if session.expire_date > timezone.now():
                    return True
            except Session.DoesNotExist:
                pass
        
        # 校验2:请求IP是否在可信内部IP列表(比如服务器本机、内网IP)
        trusted_ips = getattr(settings, 'TRUSTED_INTERNAL_IPS', ['127.0.0.1'])
        client_ip = request.META.get('REMOTE_ADDR')
        try:
            client_ip_obj = ip_address(client_ip)
            for ip_range in trusted_ips:
                if client_ip_obj in ip_network(ip_range, strict=False):
                    return True
        except ValueError:
            pass
        
        # 校验3:自定义内部请求头(需在Nginx等反向代理层限制仅内部请求能添加)
        if request.META.get('HTTP_X_INTERNAL_REQUEST') == 'true':
            return True
        
        # 校验4:兜底校验ORIGIN/REFERER(针对前端同域请求)
        allowed_origins = settings.ALLOWED_HOSTS + ['http://localhost:8000']
        origin = request.META.get('HTTP_ORIGIN')
        referer = request.META.get('HTTP_REFERER')
        if origin in allowed_origins:
            return True
        if referer and any(referer.startswith(o) for o in allowed_origins):
            return True
        
        return False

2. 灵活配置视图权限

根据不同视图的需求组合权限:

  • 允许自身应用+第三方访问:
    permission_classes = [IsFirstPartyApp | HasAPIKey]
    
  • 仅允许自身应用访问:
    permission_classes = [IsFirstPartyApp]
    
  • 仅允许第三方API Key访问:
    permission_classes = [HasAPIKey]
    
  • 需要自身登录用户或内部请求,同时还要API Key的特殊场景:
    from rest_framework.permissions import IsAuthenticated
    permission_classes = [(IsAuthenticated | IsFirstPartyApp) & HasAPIKey]
    

3. 差异化限流配置

利用DRF的限流功能,给不同认证方式的请求设置不同速率:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.ScopedRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'first_party': '1000/hour',  # 自身应用限流宽松
        'third_party': '100/hour',   # 第三方严格限流
    }
}

# 视图中动态选择限流规则(可以封装成自定义限流类更优雅)
class ExampleAPIView(APIView):
    permission_classes = [IsFirstPartyApp | HasAPIKey]
    
    def get_throttles(self):
        if IsFirstPartyApp().has_permission(self.request, self):
            self.throttle_scope = 'first_party'
        else:
            self.throttle_scope = 'third_party'
        return super().get_throttles()

额外注意点

  • 自身应用的会话认证和第三方的API Key认证要明确分工:同域前端用会话,跨域服务用API Key,不要混着来
  • 在Nginx等反向代理层做前置校验,比如拦截伪造的X-Internal-Request头,或者限制第三方API Key请求的IP范围
  • 给第三方客户端提供API Key管理界面,支持密钥轮换、权限配置
  • 记录所有API请求的认证方式、来源IP、用户信息,方便审计和排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:57:13