认证

序言

客户认证客户是不是合理合法登录。
一部分內容在DRF主视图的应用及源代码步骤剖析解读,提议首先看解读主视图的本文 。

应用步骤

认证应用的方式 步骤以下:

  1. 自定认证类 ,承继
    BaseAuthentication
    ,而且覆写其
    authenticate
    方式 。不承继
    BaseAuthentication
    还可以,但认证类中务必申明
    authenticate
    authenticate_header
    2个方式 。
  2. 当认证根据后应当回到2个值(一个元组) ,而且第一个会传送给
    request.user
    这一属性中,第二个值可能传送给
    request.auth
    这一属性中 。
  3. 假如认证不成功,则抛出异常
    APIException
    或是
    AuthenticationFailed
     ,它会全自动捕捉并回到。
  4. 当今认证类设定是全局应用還是部分应用。

自定认证类:

进行1、2 、3步,出现异常统一回到

AuthenticationFailed
 。

import jwt
from jwt import exceptions
import rest_framework.exceptions as rest_exception
from rest_framework.authentication import BaseAuthentication
from rest_framework import status
from app1.models import Login
from libs.TokenManager import SALT


class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token = request.META.get("HTTP_TOKEN")  # 在请求头中设定token值,获得的是HTTP_TOKEN
        if not token:
            raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="请在请求头中设定token值!")
        try:    # 分析token
            verified_payload = jwt.decode(token, SALT, "HS256")
            user_id, username = verified_payload["user_id"], verified_payload["username"]
            user = Login.objects.filter(user=user_id, token=token).first()
            if user:
                return user_id, username
            else:
                raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="客户不会有!")
        except exceptions.ExpiredSignatureError:
            raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token早已无效!")
        except jwt.DecodeError:
            raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token认证不成功!")
        except jwt.InvalidTokenError:
            raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token不法!")

第4步:

部分认证:

在一个必须认证的CBV里边 ,加上

authentication_classes
类属性。如:

class UserAPIView(GenericAPIView, ListModelMixin):
    authentication_classes = [MyAuthentication]
    queryset = User.objects
    serializer_class = UserSerializer

全局认证:

settings.py
里边设定:

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["libs.MyAuth.MyAuthentication"]
}

在源代码剖析一部分 ,大伙儿可能搞清楚为什么那样设定。

源代码剖析

认证的实行,是产生在

dispatch
涵数的全过程中 。

特别注意的是,封裝request的情况下 ,大家的特定的认证类也会一起封裝在新的request里边 。

接下去看一下

get_authenticators
的实行。

应用目录生成式逐个实例化了每一个authentication_classes里边的认证类。而

authentication_classes
载入了大家自定的认证类 。

注:

如果是部分认证,那麼便是大家立即给

authentication_classes
取值

如果是全局认证,那麼便是载入大家

settings
中的
DEFAULT_AUTHENTICATION_CLASSES
配备项。

以后 ,在

initial
涵数中,实行了三大认证,在其中就会有认证。

而认证立即实行了

request.user
 ,它实际上是一个被
@property
装饰设计的方式  。

接下去的实际操作全是在

rest_framework.request
控制模块里边。新封裝的request便是这下边的
Request类
的案例。

当沒有

_user
属性的情况下,表明还未认证,则会实行
_authenticate()
方式

  • 认证取得成功 ,回到元组 。
  • 认证不成功,实行
    _not_authenticated
    。

填补

最终,一个难题 ,当配备了全局认证之后 ,以后每一个插口的浏览必须实行认证,而有的托词并不一定认证或是认证的类不一样(如登录插口),应该怎么办呢?

实际上很找邦企 ,全局设定之后并不危害部分设定的起效,由于部分设定的优先超过全局设定,就例如针对登录插口而言 ,大家只必须在登录插口CBV中设定

authentication_classes
为空就可以了。如果有独特必须,还可以特定别的认证类 。

class LoginAPIView(APIView):
    authentication_classes = []
文章来源于网络,如有侵权请联系站长QQ61910465删除
本文版权归趣快排www.sEoguruBlog.com 所有,如有转发请注明来出,竞价开户托管,seo优化请联系QQ✈61910465