DRF入门- 权限认证

112 阅读3分钟

书接上回,已经做好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

image.png

image.png

image.png

权限全局配置

全局配置REST_FRAMEWORK

REST_FRAMEWORK = {
    'UNAUTHENTICATED_USER': None,
    'DEFAULT_AUTHENTICATION_CLASSES': ['api.views.MyAuthentication']
}

如果需要全局配置就不能把认证类放到视图类下面,需要单独放入一个模块中,否则会出现循环引用,报以下错误:

image.png

在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')

image.png 更改全局配置REST_FRAMEWORK 配置的选项可以通过找到APIView类中查看选项名称,这个可以不需要记,看变量名就知道作用。DEFAULT_AUTHENTICATION_CLASSES就是认证的设置名称

image.png 更改全局配置

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

image.png