如何让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
相关产品推荐
相关产品推荐

