rest_framework之认证与权限

1. 认证 :

介绍:

UserInfo表包含name , pwd , user_type三个字段
UserToken表包含token与user(关联UserInfo表)

当用户登录成功将随机字符串写入token, 并且将其返回给前台

当用户访问需要登录的视图需要将token拼到url中 , 如
http://127.0.0.1:8000/books/1?token=fbc4092d-b872-4b23-b2f7-29177ece9208
在自定义认证类里取到url的token, 与数据库的对比

源码分析

APIView---dispatch---initialize_request(包装request)---apiview的get_authenticators---
---将对象列表返回给authenticators----执行apiview的initial方法
---执行apiview的perform_authentication方法-----(request.user)
---Request.user方法----执行request对象的_authenticate方法------
循环request对象的authenticators----执行循环出的每个对象的authenticate方法,
将自己和request这个对象传入----最后返回一个元组(认证通过)
或者抛出异常(认证失败)exceptions.APIException--
--如果认证通过self.user, self.auth = user_auth_tuple执行的结果解压赋值,给request对象添加二个属性。

使用实例:

1. 自定义一个认证类 
注意:这个类要放在单独的py文件中,(如果放在view中,全局配置无法使用)
class LoginAuth():
    # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象
    def authenticate(self, request):
        # 从request对象中取出token(也可以从其它地方取)
        token = request.query_params.get('token')
        # 去数据库过滤,查询
        ret = models.UserToken.objects.filter(token=token).first()
        if ret:
            # 能查到,说明认证通过 返回两个值
            # ret.user就是当前登录用户对象,一旦retrun了,后面的认证类都不执行了
            return ret.user,ret
        # 如果查不到,抛异常
        raise exceptions.APIException('您认证失败')
        
2. 视图类中使用
- 局部使用
    在视图类中加一行:
        authentication_classes = [LoginAuth, ]
- 全局使用
    在setting中配置
        REST_FRAMEWORK={
            'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',]
        }
        中括号里的就是能导到认证类的东西
    局部禁用
        在视图类中加一行:
            authentication_classes = []

2. 权限

用法介绍

在自定义权限类里判断用户类型, 如果是3(超级会员)则权限足够, 返回Ture
如果权限不够返回False

代码实例

1. 自定义一个权限类
class UserPermission():
    # message是出错显示的中文
    message='您没有权限查看'
    def has_permission(self, request, view):
        user_type = request.user.user_type
        if user_type == 3:
            return True
        else:
            return False

2. 使用
-局部使用
    -在视图类中加一行:
     permission_classes = [UserPermission, ]

-全局使用
    -在setting中配置
    REST_FRAMEWORK={
        'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.UserPermission',]
    }
    -局部禁用
    -在视图类中加一行:
        -permission_classes = []


choice

choice的用法:
    -拿出数字对应的中文:get_字段名_dispaly()

====================================

认证组件的源码分析

执行到APIVIEW里面的dispatch方法 , 里面有一句
request = self.initialize_request(request, *args, **kwargs)
这一句会生成一个request对象, 
    生成这个对象的参数有
    django的request对象, 
    authenticators=self.get_authenticators(),
            这里的结果是authentication_classes列表里面的类实例化出来的一个个对象

然后会执行到self.initial(request, *args, **kwargs)这里
点进去里面有一句self.perform_authentication(request), 这个就是认证的

--------------------------------------------------------------------
|       分界线  上面的self代表视图类的对象  下面是Request的对象        |
--------------------------------------------------------------------

点进去里面调用了request.user, 这是一个包装过的方法, 在rest_framework.request.Request中
再进去lou一眼,里面有self._authenticate()方法,再点进去
里面会循环第六行里面的对象列表, 调用每个对象的authenticate(self)方法, 

注意!!!这里其实传了两个参数,
    第一个是对象调用方法自动将自己传过去了,
    第二个参数是request对象
源码里面会有两个变量来接收他的返回值,所以authenticate里面我们要返回两个值

总结:

综上, 所以我们需要在需要认证的视图类里面加上叫做authentication_classes的列表, 列表里面放入我们自定义的认证类

自定义认证类的时候里面需要加上方法def authenticate(self, request): ,并且返回两个值

在源码中这个方法被try了, 捕获的异常是exceptions.APIException , 所以如果认证失败抛出APIException这个异常

你可能感兴趣的:(rest_framework之认证与权限)