Django REST framework:Authentication与Permissions

一、概念

Authentication即验证,Permissions即权限。

Authentication验证是将传入请求与一组标识凭据(例如请求来自的用户或用于签名的令牌)相关联的机制。然后,Permissions权限决定了是否应该授予或拒绝访问请求。

这里一定要注意,只配置了Authentication,接口依然是可以访问的。决定接口是否能够访问需要与Permissions一起配置。

二、Authentication

1、设置验证方案的3种方式:

(1)在settings中设置全局默认身份验证方案DEFAULT_AUTHENTICATION_CLASSES:

(2)使用装饰器,在基于函数的视图上设置身份验证方案:

(3)使用APIView基于类的视图在每个视图或每个视图集的基础上设置身份验证方案:

2、身份认证类

(1)基本认证:BasicAuthentication

(2)会话认证:SessionAuthentication

(3)令牌认证:TokenAuthentication

首先,在APP中增加rest_framework.authtoken,如图:

第二,执行命令python manage.py migrate同步数据库表,auth_user表是django框架生成的用户表,接下来就使用这个表来保存用户的信息;authtoken_token表是和用户登录认证相关的数据表,用来存放用户token。

第三,我们创建一个用户,用于后期的登录测试,执行命令:python manage.py createsuperuser,创建成功后auth_user表就有了刚刚创建的数据。

接下来,我们来实现这个登录接口,编写views.py:

配置urls.py:

大家自行用接口测试工具提交post请求到登录接口,我这边就使用了DRF自带的界面操作:

按照接口定义返回了token

因为是首次登录,所以会为该用户创建token,即authtoken_token会产生一条记录:

到这里就完成了登录认证,大家可以用接口测试工具测试,如果请求头中不包含该token,那么无法获取到数据:

headers中不包含token

如果请求头中包含token,以字符串文字“Token”为前缀,用空格分隔两个字符串。例如:请求头的格式:"Authorization":"Token XXXXXXXXXXXXXXXXXXXXXXXX"

(4)第三方包DRF-JWT

JWT:json web tokens,采用json格式在web上传输的认证字符串。

DRF中对应的JWT包为:django-rest-framework-jwt,安装pip install djangorestframework-jwt,增加认证配置:

在项目的urls.py中配置:

编写views.py:

测试一下,成功:

前端的其他请求,需要在请求头中加入token,格式如下:"Authorization":"JWT ",如果希望token的前缀不要是JWT,例如是Bearer,可在settings中配置JWT_AUTH,如:

注意:由于drf-jwt的登录验证默认只支持使用username。

三、Permissions

权限决定了是否应该授予或拒绝访问请求。

权限检查总是在视图的最开始运行,在任何其他代码被允许继续之前。

权限检查通常使用request.user和request.auth属性中的身份验证信息来确定是否应允许传入请求。

1、设置权限方案的3种方式

与Authentication设置一致。

2、权限类型

IsAuthenticated:最简单的权限样式,允许任何经过身份验证的用户访问,并拒绝任何未经身份验证的用户访问。

IsAuthenticatedOrReadOnly:一种稍微不那么严格的权限样式,允许对经过身份验证的用户进行完全访问,但允许对未经身份验证的用户进行只读访问。

AllowAny:允许无限制访问。

IsAdminUser:只允许管理员用户访问。

3、自定义权限

要实现自定义权限,需要覆盖BasePermission,并实现以下任一方法或两者:

(1).has_permission(self, request, view)

(2).has_object_permission(self, request, view, obj)

(3)True表示条件通过,False表示条件不通过。

四、自定义认证与自定义权限的使用

由于drf-jwt是基于django自带的认证系统(库中的auth_user表)来实现的,我自己的库的Users表是没有username字段的,且登录验证使用字段user_no和password,所以使用pyjwt实现了令牌认证,如图,根据user_no与password生成token:

views.py中登录的token生成使用get_jwt_token方法:

生成了token之后,怎么样才能让其他接口都走这个JWT的验证机制呢?

1、自定义认证

参照官方文档:要实现自定义身份验证方案,需继承BaseAuthentication类,并使用authenticate(self, request)方法,返回user, auth。如图,新建一个myauth.py文件,这里写的比较简单,还可以加上验证token是否过期等:

配置自定义认证,我这里使用的是全局配置的方式,在settings中配置:

2、自定义权限

用户认证完成后,需要配置权限,权限决定了请求是否能够通过,要求任何经过身份验证的用户都访问,但是拒绝任何未经身份验证的用户访问。由于Users表是使用我自己创建的表,使用默认的权限('rest_framework.permissions.IsAuthenticated')会报错:not request.user.is_authenticated,所以使用自定义的权限。

新建一个myperm.py文件,写的比较简单:

配置自定义权限,我这里也是使用的是全局配置的方式,在settings中配置:

以上,就完成了一个项目最基础的验证和权限。

可以使用接口测试工具测试一下,先POST登录接口,获取JWT,在使用该用户的JWT访问其他接口,就可以获取到数据。

如果请求头中没有携带JWT或者JWT错误,是无法获取到数据的。

你可能感兴趣的:(Django REST framework:Authentication与Permissions)