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

如何让Django REST Framework仅允许超级用户访问API Web视图?

如何限制仅特定用户通过Session Authentication访问DRF API

嘿,我来帮你搞定这个需求!你现在用Django 2.0和DRF搭建API,已经配置了Token、Basic和Session三种认证方式,但目前所有认证用户都能通过浏览器登录(Session)访问API,你希望只让超级管理员这类特定用户走Session认证,普通用户只能用Token/Basic来访问对吧?

下面给你两种实用的解决方案:

方案一:自定义权限类,精准控制认证方式+用户权限

我们可以写一个自定义权限类,同时检查用户身份和当前使用的认证方式——如果是普通用户用Session访问就拒绝,超级管理员用Session或者任何用户用Token/Basic认证就放行。

先在你的app里新建一个permissions.py文件,写入以下代码:

from rest_framework import permissions
from rest_framework.authentication import SessionAuthentication

class IsSuperAdminOrNonSessionAuth(permissions.BasePermission):
    def has_permission(self, request, view):
        # 先确保用户已认证
        if not request.user.is_authenticated:
            return False
        
        # 获取当前请求使用的认证方式类型
        used_auth_types = [type(auth) for auth in request.auth] if request.auth else []
        
        # 如果用的是Session认证,必须是超级管理员才行
        if SessionAuthentication in used_auth_types:
            return request.user.is_superuser
        # 非Session认证(Token/Basic),只要已认证就允许访问
        return True

然后修改你的ContactViewSet,替换权限类:

from rest_framework import viewsets
from .models import Contact
from .serializers import ContactSerializer
from .permissions import IsSuperAdminOrNonSessionAuth  # 导入自定义权限类

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsSuperAdminOrNonSessionAuth,)  # 替换成自定义权限
    
    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

方案二:动态切换允许的认证类

另一种思路是根据用户类型动态调整允许的认证方式:超级管理员可以用所有认证方式,普通用户直接禁用Session认证,从根源上阻止他们通过浏览器登录访问。

直接修改你的ContactViewSet,重写get_authentication_classes方法:

from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication, BasicAuthentication, SessionAuthentication
from .models import Contact
from .serializers import ContactSerializer
from rest_framework.permissions import IsAuthenticated

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated,)
    
    def get_authentication_classes(self):
        # 如果当前用户是超级管理员,保留所有认证方式
        if self.request.user.is_superuser:
            return [TokenAuthentication, BasicAuthentication, SessionAuthentication]
        # 普通用户只允许Token和Basic认证,禁用Session
        return [TokenAuthentication, BasicAuthentication]
    
    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

小提示

  • 方案一更灵活,适合需要精细控制“谁能用哪种方式访问”的场景;
  • 方案二更直接,通过移除普通用户的Session认证权限,彻底避免他们用浏览器登录API;
  • 如果你其实是想只让超级管理员访问API,不管用什么认证方式,那直接用DRF内置的IsAdminUser权限类就行,但看你的描述应该是要区分认证方式的限制~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:41:16