书接上回,已经做好DRF的诞生和环境准备,这次聊一聊权限的快速使用。
权限认证基本使用
现在有一个需求,网站有个首页,有一个用户页面,一个用户登录页面。首页和用户页面需要登录后才可以访问,登录页面不需要登录,新建三个视图类:
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
# 1.返回元组分别对应,user,auth
# return ('111', '222')
# 2.抛出异常
raise AuthenticationFailed('认证失败')
# 3.返回None,用于多认证
return None
class HomeView(APIView):
authentication_classes = [MyAuthentication, ]
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'get请求成功'})
def post(self, request, ):
return Response({'status': 0, 'msg': 'post请求成功'})
def put(self, request, ):
return Response({'status': 0, 'msg': 'put请求成功'})
def delete(self, request, ):
return Response({'status': 0, 'msg': 'delete请求成功'})
class UserView(APIView):
authentication_classes = [MyAuthentication, ]
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'UserView'})
class LoginView(APIView):
authentication_classes = []
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'LoginView'})
路由urls.py
from django.urls import path
from api import views
urlpatterns = [
path('home/', views.HomeView.as_view(), name='home'),
path('login/', views.LoginView.as_view(), name='login'),
path('user/', views.UserView.as_view(), name='user'),
]
可以正常访问,拿到返回的user和auth
权限全局配置
全局配置REST_FRAMEWORK
REST_FRAMEWORK = {
'UNAUTHENTICATED_USER': None,
'DEFAULT_AUTHENTICATION_CLASSES': ['api.views.MyAuthentication']
}
如果需要全局配置就不能把认证类放到视图类下面,需要单独放入一个模块中,否则会出现循环引用,报以下错误:
在api的app中新建auth.py,把认证类放到此模块中
auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
"""
认证返回值有三类:
# 1.返回元组分别对应,user,auth
return ('111', '222')
# 2.抛出异常
# raise AuthenticationFailed('认证失败')
# 3.返回None,用于多认证
# return None
:param request:
:return:
"""
return ('111', '222')
更改全局配置REST_FRAMEWORK
配置的选项可以通过找到APIView类中查看选项名称,这个可以不需要记,看变量名就知道作用。
DEFAULT_AUTHENTICATION_CLASSES就是认证的设置名称
更改全局配置
REST_FRAMEWORK = {
'UNAUTHENTICATED_USER': None,
'DEFAULT_AUTHENTICATION_CLASSES': ['api.auth.MyAuthentication']
}
视图中不需要在添加认证类,login视图类不需要认证设置authentication_classes = []
当同时设置了全局和视图类中的认证,self调用的时候会使用自己类中的设置。不会使用全局的配置。
总结一句:视图类中的设置高于全局的。
就像你使用一个工具自己家有,肯定就先使用自己家的,不会去找别人借工具来使用,如果自己家没有就用别人提供的
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class HomeView(APIView):
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'get请求成功'})
def post(self, request, ):
return Response({'status': 0, 'msg': 'post请求成功'})
def put(self, request, ):
return Response({'status': 0, 'msg': 'put请求成功'})
def delete(self, request, ):
return Response({'status': 0, 'msg': 'delete请求成功'})
class UserView(APIView):
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'UserView'})
class LoginView(APIView):
authentication_classes = []
def get(self, request):
print(request.auth, request.user)
return Response({'status': 0, 'msg': 'LoginView'})
可以正常访问,拿到认证的用户和auth