一.Authentication用户认证配置

  1.四种验证及官网描述: 

BasicAuthentication

此身份验证方案使用HTTP基本身份验证,根据用户的用户名和密码进行签名。基本身份验证通常仅适用于测试。

如果成功通过身份验证,请BasicAuthentication提供以下凭据。

             .request.user将是一个Django User实例。

             .request.auth会的None

拒绝许可的未经身份验证的响应将导致HTTP 401 Unauthorized使用适当的WWW-Authenticate标头进行响应。例如:

                                   WWW-Authenticate: Basic realm="api"

                                 注意:如果您BasicAuthentication在生产中使用,则必须确保您的API仅可用于https。您还应该确保您的API客户端始终在登录时重新请求用户名和密码,并且永远不会将这些详细信息存储到持久存储中。

       

TokenAuthentication

此身份验证方案使用基于令牌的简单HTTP身份验证方案。令牌认证适用于客户端 - 服务器设置,例如本机桌面和移动客户端。

        要使用该TokenAuthentication方案,您需要配置要包含的身份验证类TokenAuthentication,并rest_framework.authtoken在您的INSTALLED_APPS设置中另外包含:

        INSTALLED_APPS = (
             ...
           'rest_framework.authtoken'
              )

        注意:确保manage.py migrate在更改设置后运行。该rest_framework.authtoken应用程序提供Django数据库迁移。

SessionAuthentication

        此身份验证方案使用Django的默认会话后端进行身份验证。会话身份验证适用于与您的网站在同一会话上下文中运行的AJAX客户端。

        如果成功通过身份验证,请SessionAuthentication提供以下凭据。

          • request.user将是一个Django User实例。
          • request.auth会的None

        未经许可的未经身份验证的响应将导致HTTP 403 Forbidden响应。

        如果您使用的是AJAX风格的API与SessionAuthentication,你需要确保你有一个有效的CSRF令牌任何“不安全”的HTTP方法调用,如PUTPATCHPOSTDELETE请求。有关更多详细信息,请参阅Django CSRF文档

        警告:创建登录页面时始终使用Django的标准登录视图。这将确保您的登录视图得到适当保护。

        REST框架中的CSRF验证与标准Django的工作方式略有不同,因为需要同时支持基于会话和非会话的身份验证。这意味着只有经过身份验证的请求才需要CSRF令牌,并且可以在没有CSRF令牌的情况下发送匿名请求。此行为不适用于登录视图,登录视图应始终应用CSRF验证。

RemoteUserAuthentication

此身份验证方案允许您将身份验证委派给Web服务器,该服务器设置REMOTE_USER 环境变量。

要使用它,您必须django.contrib.auth.backends.RemoteUserBackend在您的AUTHENTICATION_BACKENDS设置中拥有(或子类) 。默认情况下,为尚不存在的用户名RemoteUserBackend创建User对象。要更改此行为和其他行为,请参阅 Django文档

         如果成功通过身份验证,请RemoteUserAuthentication提供以下凭据:

          • request.user将是一个Django User实例。
          • request.auth会的None

       有关配置身份验证方法的信息,请参阅Web服务器的文档,例如:

自定义验证

      要实现自定义身份验证方案,请子类化BaseAuthentication并覆盖该.authenticate(self, request)方法。(user, auth)如果身份验证成功,则该方法应返回两元组,None否则返回。

      在某些情况下None,您可能希望AuthenticationFailed从该.authenticate()方法引发异常,而不是返回。

      通常,您应采取的方法是:

          • 如果未尝试验证,请返回None。还将检查还在使用的任何其他身份验证方案。
          • 如果尝试进行身份验证但失败,则引发AuthenticationFailed异常。无论是否进行任何权限检查,都将立即返回错误响应,并且不会检查任何其他身份验证方案。

      您可以覆盖该.authenticate_header(self, request)方法。如果实现,它应返回一个字符串,该字符串将用作响应WWW-Authenticate中标头的值HTTP 401 Unauthorized

      如果.authenticate_header()未覆盖该方法,则在HTTP 403 Forbidden拒绝未经身份验证的请求访问时,身份验证方案将返回响应。

      注意:当请求对象.user.auth属性调用您的自定义身份验证器时,您可能会看到AttributeError重新提升为WrappedAttributeError。这是防止外部属性访问抑制原始异常所必需的。Python不会识别AttributeError来自自定义身份验证器的orginates,而是假设请求对象没有.user.auth属性。这些错误应由您的验证者修复或以其他方式处理。

  2.Token验证:

       2.1setting.py中的install-app添加app:

 #Token验证,会生成表
'rest_framework.authtoken',
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
#添加Token验证,如果Token过期,不需要登录的界面也不能访问,最好配置在具体的页面 ),

生成token表,用户登录后会创建对应的key

2.2使用时TokenAuthentication,您可能希望为客户端提供一种机制,以获取给定用户名和密码的令牌。REST框架提供了一个内置视图来提供此行为。要使用它,请将obtain_auth_token视图添加到URLconf:

from rest_framework.authtoken import views
#配置url
urlpatterns += [
url(r'^api-token-auth/', views.obtain_auth_token)
]

       2.3Django请求到响应全过程:http://www.projectsedu.com/

      2.4TokenAuthentication源码:

def get_authorization_header(request):
"""
Return request's 'Authorization:' header, as a bytestring. Hide some test client ickyness where the header can be unicode.
"""
auth = request.META.get('HTTP_AUTHORIZATION', b'')
if isinstance(auth, text_type):
# Work around django test client oddness
auth = auth.encode(HTTP_HEADER_ENCODING)
return auth

通过该函数获取Token并返回

    def authenticate(self, request):
auth = get_authorization_header(request).split() if not auth or auth[0].lower() != self.keyword.lower().encode():
return None if len(auth) == 1:
msg = _('Invalid token header. No credentials provided.')
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = _('Invalid token header. Token string should not contain spaces.')
raise exceptions.AuthenticationFailed(msg) try:
token = auth[1].decode()
except UnicodeError:
msg = _('Invalid token header. Token string should not contain invalid characters.')
raise exceptions.AuthenticationFailed(msg) return self.authenticate_credentials(token)

然后通过authenticate判断token是否合法

 def authenticate_credentials(self, key):
model = self.get_model()
try:
token = model.objects.select_related('user').get(key=key)
except model.DoesNotExist:
raise exceptions.AuthenticationFailed(_('Invalid token.')) if not token.user.is_active:
raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) return (token.user, token)

到token表中查找是否对应token

二.动态设置permission,Authentication

  1.permission权限api(这里列举几个,更多可以参考官网http://www.django-rest-framework.org/api-guide/permissions/):

    IsAuthenticated:该IsAuthenticated许可类将拒绝允许任何未认证用户,并允许许可,否则。如果您希望您的API仅供注册用户访问,则此权限适用。

    IsAdminUser:所述IsAdminUser许可类将拒绝许可给任何用户,除非user.is_staffTrue在这种情况下的许可将被允许。如果您希望只有可信管理员的子集可以访问您的API,则此权限是合适的。

    IsAuthenticatedOrReadOnly:IsAuthenticatedOrReadOnly将允许经过身份验证的用户执行任何请求。只有在请求方法是“安全”方法之一时,才允许对未经授权的用户提出请求; GETHEADOPTIONS。如果您希望API允许匿名用户具有读取权限,并且仅允许对经过身份验证的用户具有写入权限,则此权限是合适的。

  2.自定义权限:

    例子:

    以下是根据黑名单检查传入请求的IP地址的权限类的示例,如果IP已被列入黑名单,则拒绝该请求。

from rest_framework import permissions

class BlacklistPermission(permissions.BasePermission):
"""
Global permission check for blacklisted IPs.
""" def has_permission(self, request, view):
ip_addr = request.META['REMOTE_ADDR']
blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
return not blacklisted

    除了针对所有传入请求运行的全局权限之外,您还可以创建对象级权限,这些权限仅针对影响特定对象实例的操作运行。例如:

class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
""" def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True # Instance must have an attribute named `owner`.
return obj.owner == request.user

    自定义验证(可以新建一个文件):

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True # Instance must have an attribute named `owner`.
return obj.user == request.user

  views中使用验证:

......
from utils.permissions import IsOwnerOrReadOnly # Create your views here.
class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin,
mixins.DestroyModelMixin, viewsets.GenericViewSet):
'''
list:
获取用户收藏列表
retrieve:
判断某个商品是否收藏
create:
收藏商品
'''
# queryset = UserFav.objects.all()
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
......

  3.动态判断:

from rest_framework import permissions
from rest_framework import authentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
......
class UserViewset(mixins.CreateModelMixin,mixins.UpdateModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):
'''
用户
'''
serializer_class = UserRegSerializer
queryset = User.objects.all()
authentication_classes = (JSONWebTokenAuthentication,authentication.SessionAuthentication)
#更新,添加用户信息放在一起,是否登录应该动态,注册不用登录IsAuthenticated,该方法不行
# permission_classes = (permissions.IsAuthenticated) def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user=self.perform_create(serializer)
re_dict=serializer.data
payload=jwt_payload_handler(user)
re_dict['token']=jwt_encode_handler(payload)
re_dict['name']=user.name if user.name else user.username
headers = self.get_success_headers(serializer.data)
return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers) def get_serializer_class(self):
'''
重载GenericAPIView中的get_serializer_class函数,调用不同的序列化类,如果是create,
就调用UserRegSerializer序列化,否则UserDetailSerializer序列化
:return:
'''
if self.action == 'retrieve':
return UserDetailSerializer
elif self.action == 'create':
return UserRegSerializer
return UserDetailSerializer def get_permissions(self):
'''
重载APIview中的get_perimissions函数,如果是新增用户则不用登录,否则必须登录
:return:
'''
if self.action == 'retrieve':
return [permissions.IsAuthenticated()]
elif self.action == 'create':
return []
return [] def get_object(self):
'''
返回当前用户
:return:
'''
return self.request.user def perform_create(self, serializer):
return serializer.save()

  

django rest framework权限和认证的更多相关文章

  1. Django Rest framework 框架之认证使用和源码执行流程

    用这个框架需要先安装: pip3 install djangorestframework 如果写了一个CBV的东西,继承了View. # 继承Django里面View class APIView(Vi ...

  2. Django REST framework - 权限和限制

    目录 Django REST framework 权限和限制 (你能干什么) 设置权限的方法 案例 第一步: 定义一个权限类 第二步: 使用 视图级别 全局级别设置 --- 限制 (你一分钟能干多少次 ...

  3. Django rest framework ---- 权限

    Django rest framework ---- 权限 添加权限 api/utils文件夹下新建premission.py文件,代码如下: message是当没有权限时,提示的信息 # FileN ...

  4. Django REST framework 自定义(认证、权限、访问频率)组件

    本篇随笔在 "Django REST framework 初识" 基础上扩展 一.认证组件 # models.py class Account(models.Model): &qu ...

  5. Django REST framework 之JWT认证

    Json Web Token 1.JWT简介 JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 H ...

  6. Django REST framework 之 API认证

    RESTful API 认证 和 Web 应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权 ...

  7. Django REST framework 的TokenAuth认证及外键Serializer基本实现

    一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App&q ...

  8. Django REST framework基础:认证、权限、限制

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  9. Django rest framework 权限操作(源码分析)

    知识回顾http://www.cnblogs.com/ctztake/p/8419059.html 这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂, 当用户访问是 首先执 ...

随机推荐

  1. RocketMQ实现事务消息

    在RocketMQ4.3.0版本后,开放了事务消息这一特性,对于分布式事务而言,最常说的还是二阶段提交协议,那么RocketMQ的事务消息又是怎么一回事呢,这里主要带着以下几个问题来探究一下Rocke ...

  2. 【适合N卡独显电脑的环境配置】Tensorflow教程-Windows 10下安装tensorflow 1.5.0 GPU with Anaconda

    注意: 1.目前Anaconda 更新原命令activate tensorflow 改为 conda activate tensorflow 2. 目前windows with anaconda 可以 ...

  3. [python] A*算法基于栅格地图的全局路径规划

    # 所有节点的g值并没有初始化为无穷大 # 当两个子节点的f值一样时,程序选择最先搜索到的一个作为父节点加入closed # 对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径 # 最后c ...

  4. 用 virtualenv 创建隔离的 Python 运行环境

    以 Ubuntu 14.04 系统为例,安装的 Python 和 Python3 分别是 2.7.6 和 3.4.3, 但有些项目,有些模块要求特定的 Python 版本.而当前系统默认的 Pytho ...

  5. js获取访问IP、地区、、当前操作浏览器

    js获取IP.地区.当前操作浏览器有什么用呢? 我的回答是用处很多,比如现在的异地登录和对用户常用浏览器做数据分析等. 源代码如下:index.html <!DOCTYPE html> & ...

  6. 解决git commit 大文件推送失败

    //查找大文件 git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5 //根据上面查找到的hash值,筛选文 ...

  7. 《Web接口开发与自动化测试 -- 基于Python语言》---现已出版。

    终于可以购买了!! 有需要的同学通过下面链接购买. 购买来链接: https://item.jd.com/11806319423.html 为什么要出这样一本书? 首先,今年我有不少工作是跟接口自动化 ...

  8. Java多线程(一)多线程基础

    一.进程 进程是操作系统结构的基础:是一次程序的执行:是一个程序及其数据在处理机上顺序执行时所发生的活动.操作系统中,几乎所有运行中的任务对应一条进程(Process).一个程序进入内存运行,即变成一 ...

  9. Python从菜鸟到高手(8):print函数、赋值与代码块

    1.神奇的print函数   print函数相信读者一定对它不陌生,因为在前面的章节,几乎每个例子都使用了print函数,这个函数的功能就是在控制台输出文本.不过print在输出文本时还可以进行一些设 ...

  10. OSGI嵌入tomcat应用服务器(gem-web)——资源下载

    Gem-Web官网介绍: 官网地址:https://www.eclipse.org/gemini/web/download/milestones.php 1.1. 官方正式发布版 https://ww ...