Django Rest Framework默认权限配置疑问:未认证用户仍可访问视图的问题排查
解决DRF权限配置未生效,未认证用户仍能访问视图的问题
嘿,我一眼就发现问题出在哪了,两个关键细节你可能没留意到:
1. Settings配置存在拼写错误!
你写的是DEFAULT_PREMISSION_CLASSES,但DRF的正确配置键是DEFAULT_PERMISSION_CLASSES——少了一个字母r!这直接导致你的全局权限配置根本没被DRF识别,哪怕后面视图配置正确也没用。先把这个修正:
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ # 这里修正了拼写错误 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', ] }
2. 你用的是原生Django视图,DRF权限系统不生效
DRF的全局权限和认证逻辑只会作用于DRF提供的视图类或者用@api_view装饰的函数视图,你当前写的def articles_list(request):是原生Django函数视图,DRF的拦截机制不会处理它。
这里给你两种修复方案,选一个适合你的:
方案一:用DRF的@api_view装饰器改造现有函数视图
只需要给你的函数加上装饰器,替换返回的JsonResponse为DRF的Response即可:
from django.shortcuts import render from rest_framework.decorators import api_view from rest_framework.response import Response from .models import Articles from .serializers import ArticleSerializer # 用@api_view标记这是DRF的API视图,全局权限会自动生效 @api_view(['GET']) def articles_list(request): articles = Articles.objects.all() serializer = ArticleSerializer(articles, many=True) return Response(serializer.data) # 用DRF的Response替代JsonResponse @api_view(['GET']) def get_article(request, articlename): article = Articles.objects.get(name=articlename) serializer = ArticleSerializer(article, many=False) return Response(serializer.data)
如果你想单独给某个视图指定权限(覆盖全局配置),可以再加
@permission_classes([IsAuthenticated])装饰器,不过既然你已经全局配置了,这里可以不用额外写。
方案二:改用DRF的通用视图类(更推荐,代码更简洁)
DRF封装了很多通用视图,比如列表视图、详情视图,直接继承就能快速实现功能:
from rest_framework import generics from .models import Articles from .serializers import ArticleSerializer class ArticleListView(generics.ListAPIView): queryset = Articles.objects.all() serializer_class = ArticleSerializer # 全局已经配置了IsAuthenticated,这里可以省略permission_classes class ArticleDetailView(generics.RetrieveAPIView): queryset = Articles.objects.all() serializer_class = ArticleSerializer lookup_field = 'name' # 指定用name作为查询字段,默认是主键pk
然后在你的urls.py里更新路由配置:
from django.urls import path from .views import ArticleListView, ArticleDetailView urlpatterns = [ path('articles/', ArticleListView.as_view(), name='article-list'), path('articles/<str:name>/', ArticleDetailView.as_view(), name='article-detail'), ]
最后验证
重启你的Django服务,现在未登录状态下访问这些接口,应该会返回401 Unauthorized的响应,登录后就能正常访问数据了。
内容的提问来源于stack exchange,提问作者adamt
相关产品推荐
相关产品推荐

