基于用户ID/Token限制DRF的API GET请求,实现文件访问权限控制
Great question! The IsAuthenticated permission is indeed too broad for your use case—you need fine-grained, user-specific access control to ensure only the owner can view their files. Here's how to build this step by step:
1. Create a Custom Permission Class
First, we'll define a permission class that checks if the requesting user matches the user ID in the URL. This ensures only the owner can access their file list.
# permissions.py from rest_framework import permissions from rest_framework.exceptions import PermissionDenied class IsFileOwner(permissions.BasePermission): """ Custom permission to restrict file list access to the owner only. """ def has_permission(self, request, view): # Get the user ID from the URL parameters target_user_id = view.kwargs.get('user_id') # Check if the requesting user's ID matches the target user ID if str(request.user.id) != target_user_id: raise PermissionDenied("Permission Denied") return True
2. Update Your View to Use the Permission
Next, create a list view that filters files by the target user and applies our custom permission (along with IsAuthenticated to ensure only logged-in users can attempt access).
First, ensure your File model has an owner foreign key linking to Django's User model:
# models.py from django.db import models from django.contrib.auth.models import User class File(models.Model): owner = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=255) # Add other file fields (e.g., path, size, upload_date) as needed
Then build your view and serializer:
# views.py from rest_framework import generics from rest_framework.permissions import IsAuthenticated from .models import File from .serializers import FileSerializer from .permissions import IsFileOwner class UserFileListView(generics.ListAPIView): serializer_class = FileSerializer # Combine permissions: require login + owner check permission_classes = [IsAuthenticated, IsFileOwner] def get_queryset(self): # Filter files to only those belonging to the target user target_user_id = self.kwargs['user_id'] return File.objects.filter(owner_id=target_user_id)
# serializers.py from rest_framework import serializers from .models import File class FileSerializer(serializers.ModelSerializer): class Meta: model = File fields = ['id', 'name', 'owner'] # Adjust fields to match your needs
3. Configure URL Patterns
Map your view to the desired URL structure:
# urls.py from django.urls import path from .views import UserFileListView urlpatterns = [ path('api/files/<str:user_id>/', UserFileListView.as_view(), name='user-file-list'), ]
How It Works
IsAuthenticated: Ensures only logged-in users can hit the endpoint.IsFileOwner: Checks if the user making the request is the same as the user ID in the URL. If not, it returns your custom "Permission Denied" message.- The view filters the queryset to only return files owned by the target user, so even if someone bypasses the permission (unlikely), they won't see other users' files.
Optional: Adjust for ViewSets
If you're using a ModelViewSet instead of a generic list view, apply the same permission class and override get_queryset similarly:
from rest_framework import viewsets class FileViewSet(viewsets.ModelViewSet): serializer_class = FileSerializer permission_classes = [IsAuthenticated, IsFileOwner] def get_queryset(self): return File.objects.filter(owner_id=self.kwargs['user_id'])
内容的提问来源于stack exchange,提问作者denbot

