一、特殊路由映射的请求

实现用户中心信息自查,不带主键的get请求,走单查逻辑

urls.py

# 用路由组件配置,形成的映射关系是 /user/center/ => list  |  user/center/(pk)/ => retrieve
# router.register('user/center', views.UserCenterViewSet, 'center') urlpatterns = [
# ...
# /user/center/ => 单查,不能走路由组件,只能自定义配置映射关系
url('^user/center/$', views.UserCenterViewSet.as_view({'get': 'user_center'})),
]

views.py

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
class UserCenterViewSet(GenericViewSet):
permission_classes = [IsAuthenticated, ]
queryset = models.User.objects.filter(is_active=True).all()
serializer_class = serializers.UserCenterSerializer def user_center(self, request, *args, **kwargs):
# request.user就是前台带token,在经过认证组件解析出来的,
# 再经过权限组件IsAuthenticated的校验,所以request.user一定有值,就是当前登录用户
serializer = self.get_serializer(request.user)
return Response(serializer.data)

二、token刷新机制配置(了解)

生成token

def _get_token(self, user):
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token

drf-jwt直接提供刷新功能

"""
1)运用在像12306这样极少数安全性要求高的网站
2)第一个token由登录签发
3)之后的所有正常逻辑,都需要发送两次请求,第一次是刷新token的请求,第二次是正常逻辑的请求
"""

settings.py

import datetime

JWT_AUTH = {
# 配置过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(minutes=5), # 是否可刷新
'JWT_ALLOW_REFRESH': True,
# 刷新过期时间
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}

urls.py

from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
urlpatterns = [
url('^login/$', ObtainJSONWebToken.as_view()), # 登录签发token接口
url('^refresh/$', RefreshJSONWebToken.as_view()), # 刷新toekn接口
]

Postman

# 接口:/api/refresh/
# 方法:post
# 数据:{"token": "登录签发的token"}

三、认证组件项目使用:多方式登录

注意:登录是post请求

1、urls.py 路由

# 自定义登录(重点):post请求 => 查操作(签发token返回给前台) - 自定义路由映射
url('^user/login/$', views.LoginViewSet.as_view({'post': 'login'})),

2、views.py 视图

# 重点:自定义login,完成多方式登录
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
class LoginViewSet(ViewSet):
# 登录接口,要取消所有的认证与权限规则,也就是要做局部禁用操作(空配置)
authentication_classes = []
permission_classes = [] # 需要和mixins结合使用,继承GenericViewSet,不需要则继承ViewSet
# 为什么继承视图集,不去继承工具视图或视图基类,因为视图集可以自定义路由映射:
# 可以做到get映射get,get映射list,还可以做到自定义(灵活)
def login(self, request, *args, **kwargs):
serializer = serializers.LoginSerializer(data=request.data, context={'request': request}) # 自定义序列化
serializer.is_valid(raise_exception=True) # 序列化校验
token = serializer.context.get('token') # 获取token
return Response({"token": token})

3、serializers.py 序列化

from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler

# 重点:自定义login,完成多方式登录
class LoginSerializer(serializers.ModelSerializer):
# 登录请求,走的是post方法,默认post方法完成的是create入库校验,所以唯一约束的字段,会进行数据库唯一校验,导致逻辑相悖
# 需要覆盖系统字段,自定义校验规则,就可以避免完成多余的不必要校验,如唯一字段校验
username = serializers.CharField()
class Meta:
model = models.User
# 结合前台登录布局:采用账号密码登录,或手机密码登录,布局一致,所以不管账号还是手机号,都用username字段提交的
fields = ('username', 'password') def validate(self, attrs):
# 在全局钩子中,才能提供提供的所需数据,整体校验得到user
# 再就可以调用签发token算法(drf-jwt框架提供的),将user信息转换为token
# 将token存放到context属性中,传给外键视图类使用
user = self._get_user(attrs)
payload = jwt_payload_handler(user) # 内部提供的方法,生成tokrn
token = jwt_encode_handler(payload) # 内部提供的方法,生成token
self.context['token'] = token # 吧token放进context中,方便取
return attrs # 多方式登录
def _get_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
import re
if re.match(r'^1[3-9][0-9]{9}$', username):
# 手机登录
user = models.User.objects.filter(mobile=username, is_active=True).first()
elif re.match(r'^.+@.+$', username):
# 邮箱登录
user = models.User.objects.filter(email=username, is_active=True).first()
else:
# 账号登录
user = models.User.objects.filter(username=username, is_active=True).first()
if user and user.check_password(password):
return user raise ValidationError({'user': 'user error'})

4、models.py 表

from django.contrib.auth.models import AbstractUser
from django.db import models class User(AbstractUser): # settings.py中要配置
mobile = models.CharField(max_length=11, unique=True, verbose_name='移动电话')
icon = models.ImageField(upload_to='icon', default='icon/default.png', verbose_name='头像') class Meta:
db_table = 'o_user'
verbose_name_plural = '用户表' def __str__(self):
return self.username class Book(models.Model):
name = models.CharField(max_length=64, verbose_name='书名') class Meta:
db_table = 'o_book'
verbose_name_plural = '书表' def __str__(self):
return self.name class Car(models.Model):
name = models.CharField(max_length=64, verbose_name='车名') class Meta:
db_table = 'o_car'
verbose_name_plural = '车表' def __str__(self):
return self.name

四、权限组件项目使用:vip用户权限

数据准备

"""
1)User表创建两条数据
2)Group分组表创建一条数据,name叫vip
3)操作User和Group的关系表,让1号用户属于1号vip组
"""

1、permissions.py 自定义权限

from rest_framework.permissions import BasePermission

from django.contrib.auth.models import Group
class IsVipUser(BasePermission):
def has_permission(self, request, view):
if request.user and request.user.is_authenticated: # 必须是合法用户
try:
vip_group = Group.objects.get(name='vip')
if vip_group in request.user.groups.all(): # 用户可能不属于任何分组
return True # 必须是vip分组用户
except:
pass return False

2、views.py 权限视图

from .permissions import IsVipUser
class CarViewSet(ModelViewSet):
permission_classes = [IsVipUser] # 自定义校验 queryset = models.Car.objects.all()
serializer_class = serializers.CarSerializer

3、serializers.py 序列化

class CarSerializer(serializers.ModelSerializer):
class Meta:
model = models.Car
fields = ('name', )

4、urls.py 自定义路由

router.register('cars', views.CarViewSet, 'car')

5、setting.py 权限配置

from rest_framework import settings
# drf配置(把配置放在最下方)
REST_FRAMEWORK = {
# 自定义三大认证配置类们
'DEFAULT_AUTHENTICATION_CLASSES':['rest_framework_jwt.authentication.JSONWebTokenAuthentication'], # 认证
# 'DEFAULT_PERMISSION_CLASSES': [], # 权限
# 'DEFAULT_THROTTLE_CLASSES': [], # 频率
}

五、频率组件

频率限制源码分析

重点

"""
1)如何自定义频率类
2)频率校验的规则
3)自定义频率类是最常见的:短信接口一分钟只能发生一条短信
"""

系统频率类

#1)UserRateThrottle: 限制所有用户访问频率
#2)AnonRateThrottle:只限制匿名用户访问频率

自定义频率类

from rest_framework.throttling import SimpleRateThrottle
"""
1)自定义类继承SimpleRateThrottle
2)设置类实现scope,值就是一个字符串,与settings中的DEFAULT_THROTTLE_RATES进行对应
DEFAULT_THROTTLE_RATES就是设置scope绑定的类的频率规则:1/min 就代表一分钟只能访问一次
3)重写 get_cache_key(self, request, view) 方法,指定限制条件
不满足限制条件,返回None:代表对这类请求不进行频率限制
满足限制条件,返回一个字符串(是动态的):代表对这类请求进行频率限制
短信频率限制类,返回 "throttling_%(mobile)s" % {"mobile": 实际请求来的电话}
"""

1、throttles.py 自定义频率,和请求方式限制

from rest_framework.throttling import SimpleRateThrottle
# 只限制查接口的频率,不限制增删改的频率
class MethodRateThrottle(SimpleRateThrottle):
scope = 'method' # 系统的配置就放在配置文件中
def get_cache_key(self, request, view):
# 只有对get请求进行频率限制
if request.method.lower() not in ('get', 'head', 'option'):
return None # 区别不同的访问用户,之间的限制是不冲突的
if request.user.is_authenticated:
ident = request.user.pk
else:
# get_ident是BaseThrottle提供的方法,会根据请求头,区别匿名用户,
# 保证不同客户端的请求都是代表一个独立的匿名用户
ident = self.get_ident(request)
return self.cache_format % {'scope': self.scope, 'ident': ident}

2、settings.py 频率配置

REST_FRAMEWORK = {
# ...
# 频率规则配置
'DEFAULT_THROTTLE_RATES': {
# 只能设置 s,m,h,d,且只需要第一个字母匹配就ok,m = min = maaa 就代表分钟
'user': '3/min', # 配合drf提供的 UserRateThrottle 使用,限制所有用户访问频率
'anon': '3/min', # 配合drf提供的 AnonRateThrottle 使用,只限制匿名用户访问频率
'method': '3/min', # 限制请求方式频率
},
}

3、views.py 频率视图

from .permissions import IsVipUser
from .throttles import MethodRateThrottle
class CarViewSet(ModelViewSet):
permission_classes = [IsVipUser] # 自定义是否是VIP校验
throttle_classes = [MethodRateThrottle] # 自定义频率限制 queryset = models.Car.objects.all()
serializer_class = serializers.CarSerializer

六、异常组件项目使用:记录异常信息到日志文件

exception.py 处理后端异常

主要:后端异常之后一定要添加日志记录。配合日志一起使用

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
def exception_handler(exc, context):
# 只处理客户端异常,不处理服务器异常,
# 如果是客户端异常,response就是可以直接返回给前台的Response对象
response = drf_exception_handler(exc, context) if response is None:
# 没有处理的服务器异常,处理一下
# 其实给前台返回 服务器异常 几个字就行了
# 那我们处理异常模块的目的是 不管任何错误,都有必要进行日志记录(线上项目只能通过记录的日志查看出现过的错误)
response = Response({'detail': '%s' % exc}) # 需要结合日志模块进行日志记录的:项目中讲
return response

settings.py 异常配置

REST_FRAMEWORK = {
# ...
# 异常模块
# 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', # 原来的,只处理客户端异常
'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}

drf token刷新配置、认证组件(使用)、权限组件(使用)、频率组件(使用)、异常组件(使用)的更多相关文章

  1. drf认证组件、权限组件、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  2. DRF之版本控制、认证和权限组件

    一.版本控制组件 1.为什么要使用版本控制 首先我们开发项目是有多个版本的当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了像bootstrap有2.3.4版本的 ...

  3. drf三大组件之认证组件与权限组件

    复习 """ 视图家族 1.视图类:APIView.GenericAPIView APIView:作为drf的基础view:as_view()禁用csrf:dispatc ...

  4. DRF框架(六)——三大认证组件之认证组件、权限组件

    drf认证组件 用户信息表 from django.db import models from django.contrib.auth.models import AbstractUser class ...

  5. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  6. day91 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  7. 20.DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    一 认证组件 1. 局部认证组件 我们知道,我们不管路由怎么写的,对应的视图类怎么写的,都会走到dispatch方法,进行分发, 在咱们看的APIView类中的dispatch方法的源码中,有个sel ...

  8. day 89 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  9. DRF的版本、认证、权限

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们项目越来越更新~版本就越来越多~~我们不可能新的版本出了~ ...

随机推荐

  1. [bzoj2815] [洛谷P2597] [ZJOI2012] 灾难

    Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...

  2. 做.net的成为 微软mvp 是一个目标吧。

    mvp 的评比 需要好多好多 绩效考核 比如博客排名,比如发表的文章数.

  3. Jmeter之BeanShell断言使用

    1.Bean Shell常用内置变量 JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下: log:用来记录日志文件,写入到j ...

  4. cnblogs 美化主题

    Silence主题 一个简洁的主题, 不带广告,我很喜欢 cnblogs 域名解析 这需要注意一点是:github.io项目名需要和用户名一致才能正确访问,否则会报404 Markdown格式化编辑 ...

  5. zbar+opencv检测图片中的二维码或条形码

    zbar本身自带检测二维码条形码功能,这里使用opencv只是做一些简单的读取图片,灰度图片以及显示条形码和二维码时用到一些绘制 // barcode-qrcodescanner.cpp: 定义控制台 ...

  6. 拓扑排序(基于dfs+基于队列)

    经典问题-Ordering Tasks dfs函数的返回值表示是否成环,若存在有向环,则不存在拓扑排序.不包含有向环的有向图称为有向无环图(DAG) 可以借助DFS完成拓扑排序,在访问完一个结点时把他 ...

  7. Git详解之特殊工具

    前言 现在,你已经学习了管理或者维护 Git 仓库,实现代码控制所需的大多数日常命令和工作流程.你已经完成了跟踪和提交文件的基本任务,并且发挥了暂存区和轻量级的特性分支及合并的威力. 接下来你将领略到 ...

  8. CSS学习笔记--Div+Css布局实战(入门)

    基本页面布局 本教程带着大家做一个简单的页面布局 最重效果如下: 1.第一部,先创建上下左右4个DIV <!DOCTYPE html> <html> <head lang ...

  9. FFMPEG学习----使用SDL播放YUV数据

    命令行下配置: G:\Coding\Video\SDL\proj>tree /F 文件夹 PATH 列表 卷序列号为 0FD5-0CC8 G:. │ sdl.cpp │ SDL2.dll │ S ...

  10. android webview正确显示音标

    package com.example.fonttest; import android.support.v7.app.ActionBarActivity; import android.webkit ...