JWT自定义校验规则与生成、用户多种方式登陆、搜索过滤,排序,分页


            # 自定义校验token规则
            1.视图类
            from .authentications import JWTAuthentication
            
            class UserDetail1(APIView):
                permission_classes = [IsAuthenticated]  # 必须登录
                authentication_classes = [JWTAuthentication]  # jwt用户token自定义登陆认证规则
            
                def get(self, request, *args, **kwargs):
                    return APIResponse(results={username: request.user.username})
            2.自定义token规则,在api生成一个authentications.py认证文件
            import jwt
            from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
            from rest_framework_jwt.authentication import jwt_decode_handler
            from rest_framework.exceptions import AuthenticationFailed
            
            class JWTAuthentication(BaseJSONWebTokenAuthentication):
                def authenticate(self, request):
                    jwt_token = request.META.get(HTTP_AUTHORIZATION)
            
                    # 自定义规则 :auth token jwt,调用下面规则方法
                    token = self.parse_jwt_token(jwt_token)
            
                    # 如果没有值,无法校验
                    if token is None:
                        return None
            
                    try:
                        # token =>payload  反向解析出payload
                        payload = jwt_decode_handler(token)
                    except jwt.ExpiredSignature:  # 判断是否过期
                        raise AuthenticationFailed(token已过期)
                    except:
                        raise AuthenticationFailed(非法用户)
                    user = self.authenticate_credentials(payload) # 根据payload解析出user
            
                    return (user, token)
            
                # 自定义校验规则:auth token jwt ,auth为前言,jwt为后缀
                def parse_jwt_token(self, jw_token):
                    tokens = jw_token.split()
                    if len(tokens) != 3 or tokens[0].lower() != auth or tokens[2].lower() != jwt:
                        return None
                    # 把token核心内容返回进行校验
                    return tokens[1]

            # 自定义 drf-jwt 配置
            import datetime
            JWT_AUTH = {
                # user => payload
                JWT_PAYLOAD_HANDLER:
                    rest_framework_jwt.utils.jwt_payload_handler,
                # payload => token
                JWT_ENCODE_HANDLER:
                    rest_framework_jwt.utils.jwt_encode_handler,
                # token => payload
                JWT_DECODE_HANDLER:
                    rest_framework_jwt.utils.jwt_decode_handler,
                # token过期时间
                JWT_EXPIRATION_DELTA: datetime.timedelta(days=7),
                # token刷新的过期时间
                JWT_REFRESH_EXPIRATION_DELTA: datetime.timedelta(days=7),
                # 反爬小措施前缀
                JWT_AUTH_HEADER_PREFIX: JWT,
            }

            实现多种方式登录签发token:比如 -账号、手机号、邮箱等登录:
            1.禁用认证与权限组件
            2.拿到前台登录信息,交给序列化类
            3.序列化校验得到登陆用户与token存放在序列化对象中
            4.取出登陆用户与token返回给前台
            """

            from .serializers import UserModelSerializer

            # 1.视图类
            class LoginAPIView(APIView):
                authentication_classes = []  # 禁用认证
                permission_classes = []  # 禁用权限
            
                def post(self, request, *args, **kwargs):
                    user_ser = UserModelSerializer(data=request.data)  # 反序列化进行校验
                    # 校验通过,如果没有报异常
                    user_ser.is_valid(raise_exception=True)
            
                    # 正常登陆,把生成的token返回给前端
                    return APIResponse(token=user_ser.token, results=UserModelSerializer(user_ser.user).data)
              
            #2. 序列化类,进行校验,生成token发送出去
            from rest_framework import serializers
            from . import models
            import re
            
            from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
            
            class UserModelSerializer(serializers.ModelSerializer):
                # 自定义反序列化字段:一定要设置write_only,值参与反序列化,不会与model类字段映射
                usr = serializers.CharField(write_only=True)
                pwd = serializers.CharField(write_only=True)
            
                class Meta:
                    model = models.User
                    fields = [usr, pwd, username, mobile, email]
                    # 系统校验规则
                    extra_kwargs = {
                        # ‘usr‘: {
                            # ‘required‘: True,  # 必须校验
                        #     ‘min_length‘: 3,
                        #     ‘error_messages‘: {
                        #         ‘required‘: ‘必须填写,你个铺盖‘,
                        #         ‘min_length‘: ‘太短楼!‘,
                        #     }
                        # },
                        username: {
                            read_only: True
                        },
                        mobile: {
                            read_only: True
                        },
                        email: {
                            read_only: True
                        }
            
                    }
            
                # 全局钩子,attrs里面是通过校验的
                def validate(self, attrs):
                    usr = attrs.get(usr)
                    pwd = attrs.get(pwd)
                    # 多方式登录:各分支处理得到该方式对应的用户
                    if re.match(r[email protected]+, usr):
                        user_query = models.User.objects.filter(email=usr)
                    elif re.match(r1[3-9][0-9]{9}, usr):
                        user_query = models.User.objects.filter(mobile=usr)
                    else:
                        user_query = models.User.objects.filter(username=usr)
                    user_obj = user_query.first()
            
                    if user_obj and user_obj.check_password(pwd):
                        # 签发生成token,将token存放到实例化对象的中
                        payload = jwt_payload_handler(user_obj)  # 把头部,和载荷过期时间,user对象,生成payload
                        token = jwt_encode_handler(payload)  # 把头部,载荷,和秘=秘钥经过加密生成token
                        self.token = token  # 把token赋值到对象中
                        self.user = user_obj
                        print(token)
                        return attrs
                    raise serializers.ValidationError({data: 数据提供有误})
             
            搜索过滤,排序,分页:
            from . import models
            from .serializers import CarModelSerializer
            # Car的群查接口
            from rest_framework.generics import ListAPIView
            
            # 1.drf的SearchFilter - 搜索过滤
            from rest_framework.filters import SearchFilter
            
            # 2.drf的OrderingFilter - 排序过滤
            from rest_framework.filters import OrderingFilter
            
            # 3.drf的分页类 - 自定义
            from . import pagenations
            
            class CarListAPIView(ListAPIView):
                permission_classes = []  # 权限取消
                authentication_classes = []  # 认证取消
            
                queryset = models.Car.objects.all()
                serializer_class = CarModelSerializer
            
                # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
                filter_backends = [SearchFilter,OrderingFilter]
            
                # SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
                search_fields = [name, price]
            
                # OrderingFilter过滤类依赖的过滤条件 => 接口:/cars/?ordering=...,正是升序,-则是降序
                ordering_fields = [pk, price]
                # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序
            
                pagination_class = pagenations.MyPageNumberPagination
             
            # 自定义分页类
            from rest_framework.pagination import PageNumberPagination
            
            class MyPageNumberPagination(PageNumberPagination):
                # ?page=页码
                page_query_param = page
            
                # ?page=页面 下默认一页显示的条数
                page_size = 3
            
                # ?page=页面&page_size=条数 用户自定义一页显示的条数
                page_size_query_param = page_size
            
                max_page_size = 5
            相关文章
            相关标签/搜索
            每日一句
              每一个你不满意的现在,都有一个你没有努力的曾经。
            公众号推荐
               一个历史类的公众号,欢迎关注
            一两拨千金
            2020王中王资料一肖中2018年香港开奖日期表2018香港历史开奖结果香港最快开奖现场直播 祁阳县| 永修县| 五台县| 勃利县| 宝清县| 屏山县| 宁南县| 嘉黎县| 塔河县| 新余市| 金湖县| 阳城县| 河北省| 英德市| 曲阳县| 横山县| 翁源县| 高清| 阜康市| 焦作市| 泾阳县| 娄底市| 武汉市| 大悟县| 泰宁县| 黄骅市| 特克斯县| 沙湾县| 雷山县| 博客| 兴宁市| 临泉县| 赤壁市| 宁城县| 阜宁县| 淮滨县| 大宁县| 高雄县| 宝坻区| 当雄县| 崇义县| 东城区| 林芝县| 高尔夫| 宜阳县| 马公市| 遂昌县| 阜康市| 育儿| 台安县| 财经| 南阳市| 蓝山县| 沙河市| 南郑县| 二连浩特市| 克山县| 江孜县| 黄平县| 海晏县| 临城县| 遵化市| 扎兰屯市| 新宁县| 汝阳县| 汝城县| 余江县| 台南市| 西乌| 灵川县| 页游| 怀化市| 湘潭市| 桑日县| 清河县| 靖宇县| 六枝特区| 沅陵县| 乐昌市| 和田县| 马尔康县| 云阳县| 南汇区| 田林县| 锡林浩特市| 扎囊县| 门源| 沽源县| 双辽市| 南平市| 文安县| 湟中县| 新和县| 镇康县| 永川市| 定州市| 社会| 永昌县| 湘乡市| 崇信县| 黑山县| 龙南县| 鹤山市| 平顺县| 武乡县| 五大连池市| 拜泉县| 西乌珠穆沁旗| 扶绥县| 梅河口市| 曲沃县| 新沂市| 浏阳市| 西安市| 沁水县| 邹城市| 高密市| 龙山县| 马山县| 商城县| 壶关县| 邻水| 深圳市| 墨竹工卡县| 竹溪县| 岳阳县| 于田县| 伊通| 丘北县| 崇阳县| 鹤壁市| 黄石市| 内黄县| 吉林省| 静宁县| 通城县| 沿河| 保亭| 雷山县| 清远市| 项城市| 湖北省| 威信县| 台北县| 阿图什市| 舟山市| 博野县| 雷山县| 湖口县| 顺义区| 浦北县| 石柱| 奉节县| 沁源县| 禹州市| 若尔盖县| 开平市| 随州市| 如东县| 泊头市| 门源| 宁晋县| 永善县| 湘阴县| 依兰县| 临泽县| 靖江市| 敦煌市| 化德县| 黄浦区| 治多县| 灵寿县| 铁岭市| 巴林左旗| 雷波县| 平利县| 平利县| 博罗县| 定兴县| 化州市| 和林格尔县| 拜城县| 东台市| 洞口县| 临桂县| 海伦市| 广昌县| 徐州市| 汤阴县| 金湖县| 台东县| 嵩明县| 昌乐县| 离岛区| 姜堰市| 开阳县| 秀山| 昌宁县| 江山市| 南宁市| 盈江县| 琼中| 东阿县| 郸城县| 辽源市| 会泽县| 钟山县| 汉川市| 海口市| 靖宇县| 泰安市| 新竹市| 南丰县| 若尔盖县| 雷山县| 库尔勒市| 吉木萨尔县| 大余县| 株洲市| 梅河口市| 和政县| 合水县| 浦县| 武清区| 宁明县| 西乌| 宾川县| 明星| 辰溪县| 石城县| 淮滨县| 昌乐县| 咸宁市| 新建县| 四会市| 安阳县| 河西区| 乐都县| 延寿县| 西乡县| 满洲里市| 当涂县| 隆安县| 渭南市| 南平市| 丹阳市| 吴川市| 兴业县| 临海市| 阿拉善盟| 库尔勒市| 桂东县| 南京市| 翼城县| 澄迈县| 西青区| 南丹县| 乌鲁木齐县| 怀宁县| 色达县| 布尔津县| 盐边县| 青川县| 汕尾市| 长垣县| 突泉县| 屏东县| 文昌市| 邹城市| 庆云县| 屏边| 宣威市| 福海县| 集安市| 平泉县| 昔阳县| 武夷山市| 泰州市| 建阳市| 凌源市| 康保县| 东乡| 霍林郭勒市| 天镇县| 海丰县| 宁安市| 怀远县| 思南县| 双辽市| 寿光市| 白银市| 乌鲁木齐县| 鄂托克旗| 靖远县| 绥江县| 大方县| 龙井市| 通化市| 应城市| 镇沅| 洪雅县| 苏尼特左旗| 潮州市| 边坝县| 延安市| 沙河市| 科技| 通化市| 镇安县| 电白县| 广昌县| 绥中县| 永宁县| 温州市| 隆德县| 和田市| 虹口区| 洛川县| 晋城| 湟源县| 阿合奇县| 琼海市| 怀柔区| 盐池县| 北宁市| 奈曼旗| 札达县| 五家渠市| 哈尔滨市| 侯马市| 旬邑县| 仪征市| 陆良县| 彩票| 宜兰县| 石景山区| 黄龙县| 民乐县| 彰化市| 海林市| 罗城| 宁明县| 沈丘县| 六枝特区| 榕江县| 闽侯县| 横山县| 长海县| 淄博市| 景德镇市| 祁门县| 梅河口市| 大安市| 江永县| 湘乡市| 田林县| 祁阳县| 东港市| 离岛区| 临沂市| 沙湾县| 上栗县| 南郑县| 翁牛特旗| 金华市| 昌都县| 宣化县| 水富县| 焦作市| 通山县| 建湖县| 辽宁省| 台东县| 井陉县| 合阳县| 上蔡县| 彰化县| 叙永县| 南投市| 松阳县| 田东县| 苗栗县| 永嘉县| 双鸭山市| 涟水县| 德安县| 琼海市| 盐津县| 遵义市| 绥宁县| 永城市| 逊克县| 红原县| 鸡东县| 新竹县| 资阳市| 深水埗区| 平湖市| 雷州市| 常德市| 金堂县| 当雄县| 商水县| 汕头市| 寿光市| 莆田市| 武清区| 福贡县| 蒙城县| 泾阳县| 青冈县| 泸西县| 江都市| 威远县| 临沧市| 潢川县| 达州市| 湘潭市| 汝南县| 东兰县| 邹平县| 隆尧县| 建宁县| 勃利县| 额敏县| 长兴县| 赫章县| 乌兰察布市| 马尔康县| 长汀县| 息烽县| 澄城县| 西乌| 松桃| 镇巴县| 乐至县| 大姚县| 海口市| 平乐县| 沁阳市| 温州市| 定边县| 新兴县| 石门县| 西藏| 城市| 兰西县| 砚山县| 泾源县| 雷州市| 镇原县| 德惠市| 贵溪市| 邵东县| 卫辉市| 闽清县| 互助| 潮州市| 驻马店市| 教育| 当涂县| 镇坪县| 北安市| 武隆县| 南投县| 邵武市| 河源市| 西充县| 金川县| 临泽县| 临漳县| 南宫市| 承德县| 竹北市| 芒康县| 石首市| 饶河县| 蓬溪县| 海宁市| 格尔木市| 木兰县| 昭通市| 东丽区| 射阳县| 渑池县| 东阿县| 武夷山市| 陆河县| 九寨沟县| 沂源县| 闽侯县| 穆棱市| 柏乡县| 渝中区| 射阳县| 房山区| 泸溪县| 凤城市| 清流县| 揭东县| 贞丰县| 琼中| 彝良县| 个旧市| 定结县| 洪雅县| 商河县| 禹州市| 安陆市| 岳西县| 航空| 北宁市| 玛沁县| 清流县| 泸西县| 西乌珠穆沁旗| 莱州市| 琼结县| 沛县| 土默特左旗| 伊川县| 利川市| 庐江县| 扬州市| 天气| 阳江市| 武宁县| 西贡区| 平安县| 嘉鱼县| 五大连池市| 邢台市| 射洪县| 宁晋县| 蓬莱市| 西城区| 颍上县| 钟祥市| 鱼台县| 绵阳市| 林周县| 桃源县| 海阳市| 保德县| 大埔区| 资中县| 大石桥市| 八宿县| 盐山县| 六安市| 乐山市| 靖宇县| 金阳县| 环江| 达拉特旗| 金乡县| 昂仁县| 高台县| 丘北县| 修武县| 汤原县| 武安市| 清水县| 金沙县| 张家港市| 思茅市| 襄垣县| 德清县| 防城港市| 井陉县| 苍南县| 聂荣县| 彭阳县| 安国市| 张家港市| 屏南县| 绥中县| 二手房| 荔波县| 措勤县| 双峰县| 连云港市| 廊坊市| 昆明市| 久治县| 通州市| 惠来县| 清水县| 和林格尔县| 江永县| 泗水县| 郸城县| 泗洪县| 绥化市| 襄汾县| 涿州市| 昭苏县| 龙里县| 东乌珠穆沁旗| 临夏县| 文登市| 肃南| 登封市| 阿坝| 马鞍山市| 榕江县| 维西| 石景山区| 尤溪县| 婺源县| 十堰市| 随州市| 上犹县| 满城县| 舟曲县| http://www.jx1870fieldv.fun http://m.jx1870fishv.fun http://jx1870judgev.fun http://www.jx1870leaguev.fun http://www.jx1870huzorv.fun http://www.jx1870icev.fun http://wap.jx1870googlev.fun http://m.jx1870glassv.fun http://wap.jx1870generalv.fun http://m.jx1870foxv.fun http://www.jx1870flowerv.fun http://www.jx1870focusv.fun http://jx1870givev.fun http://www.jx1870forestv.fun http://m.jx1870installv.fun http://wap.hz0j1r9vo.fun http://wap.jx1870hidev.fun http://www.jx1870labourv.fun