Django-Rest frameworw认证和权限

一、认证已封装好的类

	from rest_framework.authentication import BaseAuthentication
	class BaseAuthentication(object):
		def authenticate(self, request):
			#三种返回结果
			1、 return (user,auth) #当前认证处理后,认证环节结束,不在执行后面的认证了
			2、 return None  #不处理,让后面认证处理
			3、 raise  raise #exceptions.AuthenticationFailed("用户认证失败")


		def authenticate_header(self, request):
			# 验证失败时,返回的响应头WWW-Authenticate对应的值
			pass

	class BasicAuthentication(BaseAuthentication):
		'请求头认证'
		pass

	class SessionAuthentication(BaseAuthentication):
		'session认证'
		pass
	class TokenAuthentication(BaseAuthentication):
		'token认证,' 
		pass

二、权限已封装好的类

from rest_framework.permissions import BasePermission
class BasePermission(object):
	

	message = "权限验证失败" #定制验证的错误信息

	def has_permission(self, request, view):
		'判断是否有权限访问当前请求'
		return True #/ False

	# GenericAPIView中get_object时调用
	def has_object_permission(self, request, view, obj):
		'视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证'
		return True # / False

class AllowAny(BasePermission):
	'任何人都能访问,和没设置一样'
	def has_permission(self, request, view):
	return True

class IsAuthenticated(BasePermission):
	'登录后,才能访问'
	def has_permission(self, request, view):
    return request.user and request.user.is_authenticated

class IsAdminUser(BasePermission):
	'只允许,admin用户访问'

class IsAuthenticatedOrReadOnly(BasePermission):
	'登录后,请求方式允许(get , put) 才能访问 '

class DjangoModelPermissions(BasePermission):
	'不清楚'

1、def authenticate_header(self, request): #作用

Django-Rest frameworw认证和权限_第1张图片

生成这样的登录界面(浏览器自带的登录界面)

Django-Rest frameworw认证和权限_第2张图片


三、认证示例展示

============*****============

        1、用户url传入的token认证     #局部 或 全局类使用

        2、请求头认证

        3. 多个认证规则

        4.认证和权限

============*****============

   1、用户url传入的token认证

in url.py
	from django.conf.urls import url, include
	from web.viewsimport TestView

	urlpatterns = [
		url(r'^test/', TestView.as_view()),
	]


in view.py
	from rest_framework.views import APIView
	from rest_framework.response import Response
	from rest_framework.authentication import BaseAuthentication
	from rest_framework.request import Request
	from rest_framework import exceptions

	token_list = [
	    'sfsfss123kuf3j123',
	    'asijnfowerkkf9812',
	]


	class TestAuthentication(BaseAuthentication):
	    def authenticate(self, request):
	        """
	        用户认证,如果验证成功后返回元组: (用户,用户Token)
	        :param request: 
	        :return: 
	            None,表示跳过该验证;
	                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
	                self._authenticator = None
	                if api_settings.UNAUTHENTICATED_USER:
	                    self.user = api_settings.UNAUTHENTICATED_USER()
	                else:
	                    self.user = None
	        
	                if api_settings.UNAUTHENTICATED_TOKEN:
	                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()
	                else:
	                    self.auth = None
	            (user,token)表示验证通过并设置用户名和Token;
	            AuthenticationFailed异常
	        """
	        val = request.query_params.get('token')
	        if val not in token_list:
	            raise exceptions.AuthenticationFailed("用户认证失败")

	        return ('登录用户', '用户token')

	    def authenticate_header(self, request):
	        """
	        Return a string to be used as the value of the `WWW-Authenticate`
	        header in a `401 Unauthenticated` response, or `None` if the
	        authentication scheme should return `403 Permission Denied` responses.
	        """
	        # 验证失败时,返回的响应头WWW-Authenticate对应的值
	        pass

	方式一:定义局部类(认证、权限等)
		class TestView(APIView):
		    authentication_classes = [TestAuthentication, ]
		    permission_classes = []

		    def get(self, request, *args, **kwargs):
		        print(request.user)
		        print(request.auth)
		        return Response('GET请求,响应内容')

		    def post(self, request, *args, **kwargs):
		        return Response('POST请求,响应内容')

		    def put(self, request, *args, **kwargs):
		        return Response('PUT请求,响应内容')


	方式二:(推荐)在使用局部类 ,或者TestView不想使用全局的类(认证、权限等)

		class MyTokenAuthentication(object):
			authentication_classes = [TestAuthentication, ] 
			permission_classes = []

		class TestView(MyTokenAuthentication,APIView): #MyTokenAuthentication 要放在前面,
						#否则authentication_classes 就从全局(settings)里找

		    def get(self, request, *args, **kwargs):
		        print(request.user)
		        print(request.auth)
		        return Response('GET请求,响应内容')

		    def post(self, request, *args, **kwargs):
		        return Response('POST请求,响应内容')

		    def put(self, request, *args, **kwargs):
		        return Response('PUT请求,响应内容')
    2、请求头认证
in url.py
	from django.conf.urls import url, include
	from web.viewsimport TestView

	urlpatterns = [
		url(r'^test/', TestView.as_view()),
	]

in view.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	from rest_framework.views import APIView
	from rest_framework.response import Response
	from rest_framework.authentication import BaseAuthentication
	from rest_framework.request import Request
	from rest_framework import exceptions

	token_list = [
	    'sfsfss123kuf3j123',
	    'asijnfowerkkf9812',
	]


	class TestAuthentication(BaseAuthentication):
	    def authenticate(self, request):
	        """
	        用户认证,如果验证成功后返回元组: (用户,用户Token)
	        :param request: 
	        :return: 
	            None,表示跳过该验证;
	                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
	                self._authenticator = None
	                if api_settings.UNAUTHENTICATED_USER:
	                    self.user = api_settings.UNAUTHENTICATED_USER()
	                else:
	                    self.user = None
	        
	                if api_settings.UNAUTHENTICATED_TOKEN:
	                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()
	                else:
	                    self.auth = None
	            (user,token)表示验证通过并设置用户名和Token;
	            AuthenticationFailed异常
	        """
	        import base64
	        auth = request.META.get('HTTP_AUTHORIZATION', b'')
	        if auth:
	            auth = auth.encode('utf-8')
	        auth = auth.split()
	        if not auth or auth[0].lower() != b'basic':
	            raise exceptions.AuthenticationFailed('验证失败')
	        if len(auth) != 2:
	            raise exceptions.AuthenticationFailed('验证失败')
	        username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':') # partition 切割和split类似,
	        if username == 'alex' and password == '123':                      # 但 'xxx:yyy'.partition(":") = ['xxx',':','yyy']
	            return ('登录用户', '用户token')
	        else:
	            raise exceptions.AuthenticationFailed('用户名或密码错误')

	    def authenticate_header(self, request):
	        """
	        Return a string to be used as the value of the `WWW-Authenticate`
	        header in a `401 Unauthenticated` response, or `None` if the
	        authentication scheme should return `403 Permission Denied` responses.
	        """
	        return 'Basic realm=api'


	class TestView(APIView): # 关注  1、用户url传入的token认证 的TestView使用
	    authentication_classes = [TestAuthentication, ] 
	    permission_classes = []

	    def get(self, request, *args, **kwargs):
	        print(request.user)
	        print(request.auth)
	        return Response('GET请求,响应内容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST请求,响应内容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT请求,响应内容')
3. 多个认证规则
in url.py
	from django.conf.urls import url, include
	from web.views.s2_auth import TestView

	urlpatterns = [
	    url(r'^test/', TestView.as_view()),
	]

in view.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	from rest_framework.views import APIView
	from rest_framework.response import Response
	from rest_framework.authentication import BaseAuthentication
	from rest_framework.request import Request
	from rest_framework import exceptions

	token_list = [
	    'sfsfss123kuf3j123',
	    'asijnfowerkkf9812',
	]


	class Test1Authentication(BaseAuthentication):
	    def authenticate(self, request):
	        """
	        用户认证,如果验证成功后返回元组: (用户,用户Token)
	        :param request: 
	        :return: 
	            None,表示跳过该验证;
	                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
	                self._authenticator = None
	                if api_settings.UNAUTHENTICATED_USER:
	                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户
	                else:
	                    self.user = None

	                if api_settings.UNAUTHENTICATED_TOKEN:
	                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None
	                else:
	                    self.auth = None
	            (user,token)表示验证通过并设置用户名和Token;
	            AuthenticationFailed异常
	        """
	        import base64
	        auth = request.META.get('HTTP_AUTHORIZATION', b'')
	        if auth:
	            auth = auth.encode('utf-8')
	        else:
	            return None
	        print(auth,'xxxx')
	        auth = auth.split()
	        if not auth or auth[0].lower() != b'basic':
	            raise exceptions.AuthenticationFailed('验证失败')
	        if len(auth) != 2:
	            raise exceptions.AuthenticationFailed('验证失败')
	        username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':')
	        if username == 'alex' and password == '123':
	            return ('登录用户', '用户token')
	        else:
	            raise exceptions.AuthenticationFailed('用户名或密码错误')

	    def authenticate_header(self, request):
	        """
	        Return a string to be used as the value of the `WWW-Authenticate`
	        header in a `401 Unauthenticated` response, or `None` if the
	        authentication scheme should return `403 Permission Denied` responses.
	        """
	        # return 'Basic realm=api'
	        pass

	class Test2Authentication(BaseAuthentication):
	    def authenticate(self, request):
	        """
	        用户认证,如果验证成功后返回元组: (用户,用户Token)
	        :param request: 
	        :return: 
	            None,表示跳过该验证;
	                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
	                self._authenticator = None
	                if api_settings.UNAUTHENTICATED_USER:
	                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户
	                else:
	                    self.user = None
	        
	                if api_settings.UNAUTHENTICATED_TOKEN:
	                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None
	                else:
	                    self.auth = None
	            (user,token)表示验证通过并设置用户名和Token;
	            AuthenticationFailed异常
	        """
	        val = request.query_params.get('token')
	        if val not in token_list:
	            raise exceptions.AuthenticationFailed("用户认证失败")

	        return ('登录用户', '用户token')

	    def authenticate_header(self, request):
	        """
	        Return a string to be used as the value of the `WWW-Authenticate`
	        header in a `401 Unauthenticated` response, or `None` if the
	        authentication scheme should return `403 Permission Denied` responses.
	        """
	        pass


	class TestView(APIView):
	    authentication_classes = [Test1Authentication, Test2Authentication]  # 某个认证处理完就结束了,之后的认证失效
	    permission_classes = [] # 权限是每个类都要经过




	    def get(self, request, *args, **kwargs):
	        print(request.user)
	        print(request.auth)
	        return Response('GET请求,响应内容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST请求,响应内容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT请求,响应内容')

4.认证和权限

in url.py
	from django.conf.urls import url, include
	from web.views import TestView

	urlpatterns = [
	    url(r'^test/', TestView.as_view()),
	]

in view.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	from rest_framework.views import APIView
	from rest_framework.response import Response
	from rest_framework.authentication import BaseAuthentication
	from rest_framework.permissions import BasePermission

	from rest_framework.request import Request
	from rest_framework import exceptions

	token_list = [
	    'sfsfss123kuf3j123',
	    'asijnfowerkkf9812',
	]


	class TestAuthentication(BaseAuthentication):
	    def authenticate(self, request):
	        """
	        用户认证,如果验证成功后返回元组: (用户,用户Token)
	        :param request: 
	        :return: 
	            None,表示跳过该验证;
	                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
	                self._authenticator = None
	                if api_settings.UNAUTHENTICATED_USER:
	                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户
	                else:
	                    self.user = None
	        
	                if api_settings.UNAUTHENTICATED_TOKEN:
	                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None
	                else:
	                    self.auth = None
	            (user,token)表示验证通过并设置用户名和Token;
	            AuthenticationFailed异常
	        """
	        val = request.query_params.get('token')
	        if val not in token_list:
	            raise exceptions.AuthenticationFailed("用户认证失败")

	        return ('登录用户', '用户token')

	    def authenticate_header(self, request):
	        """
	        Return a string to be used as the value of the `WWW-Authenticate`
	        header in a `401 Unauthenticated` response, or `None` if the
	        authentication scheme should return `403 Permission Denied` responses.
	        """
	        pass


	class TestPermission(BasePermission):
	    message = "权限验证失败" # 错误信息

	    def has_permission(self, request, view):
	        """
	        判断是否有权限访问当前请求
	        两种返回结果
		        return True  # 权限验证通过,执行下一个权限类
		        return False # 检测为False  然后就raise 报错  
	        """
	        if request.user == "管理员":
	            return True

	    # GenericAPIView中get_object时调用
	    def has_object_permission(self, request, view, obj):
	        """
	        视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证
	        Return `True` if permission is granted, `False` otherwise.
	        :param request: 
	        :param view: 
	        :param obj: 
	        :return: True有权限;False无权限
	        """
	        if request.user == "管理员":
	            return True


	class TestView(APIView):
	    # 认证的动作是由request.user触发
	    authentication_classes = [TestAuthentication, ]

	    # 权限
	    # 循环执行所有的权限
	    permission_classes = [TestPermission, ]

	    def get(self, request, *args, **kwargs):
	        # self.dispatch
	        print(request.user)
	        print(request.auth)
	        return Response('GET请求,响应内容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST请求,响应内容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT请求,响应内容')





你可能感兴趣的:(Rest,framework)