自定义类签发校验token-实现多方式登录-自定义反爬类-admin后台表管理字段自定义-群查接口-搜索-排序-分页

            复习

            """
            频率组件:限制接口的访问频率
                源码分析:初始化方法、判断是否有权限方法、计数等待时间方法
                自定义频率组件:
                class MyThrottle(SimpleRateThrottle):
                    scope = 'sms'
                    def get_cache_key(self, request, view):
                        # 从request的 query_params、data、META 及 view 中 获取限制的条件
                        return '与认证信息有关的动态字符串'
                    
                settings文件中要有scope对应的rate配置 {'sms': '3/min'}
                
            jwt认证:
                1)session存储token,需要数据库参与,耗服务器资源、低效
                2)缓存存token,需要缓存参与,高效,不易集群
                3)客户端存token,服务器存签发与交易token的算法,高效,易集群
            
            drf-jwt使用:
                安装:djangorestframework-jwt
                视图类签发token - username,password => token
                认证类校验token - token => user
                
            jwt格式:基本信息(头base64).用户信息过期时间(载荷base64).所有信息+秘钥(签名HS256)
            """

            今日

            """
            1、drf-jwt手动签发与校验
            2、drf小组件:过滤、筛选、排序、分页 => 针对与群查接口
            """

            签发token

            源码入口
            # 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口
            
            # 1)rest_framework_jwt.views.ObtainJSONWebToken 的 父类 JSONWebTokenAPIView 的 post 方法
            #       接受有username、password的post请求
            # 2)post方法将请求数据交给 rest_framework_jwt.serializer.JSONWebTokenSerializer 处理
            #       完成数据的校验,会走序列化类的 全局钩子校验规则,校验得到登录用户并签发token存储在序列化对象中
            核心源码:rest_framework_jwt.serializer.JSONWebTokenSerializer的validate(self, attrs)方法
            def validate(self, attrs):
                # 账号密码字典
                credentials = {
                    self.username_field: attrs.get(self.username_field),
                    'password': attrs.get('password')
                }
                if all(credentials.values()):
                    # 签发token第1步:用账号密码得到user对象
                    user = authenticate(**credentials)
                    if user:
                        if not user.is_active:
                            msg = _('User account is disabled.')
                            raise serializers.ValidationError(msg)
                        # 签发token第2步:通过user得到payload,payload包含着用户信息与过期时间
                        payload = jwt_payload_handler(user)
                        # 在视图类中,可以通过 序列化对象.object.get('user'或者'token') 拿到user和token 
                        return {
                            # 签发token第3步:通过payload签发出token
                            'token': jwt_encode_handler(payload),
                            'user': user
                        }
                    else:
                        msg = _('Unable to log in with provided credentials.')
                        raise serializers.ValidationError(msg)
                else:
                    msg = _('Must include "{username_field}" and "password".')
                    msg = msg.format(username_field=self.username_field)
                    raise serializers.ValidationError(msg)
            手动签发token逻辑
            # 1)通过username、password得到user对象
            # 2)通过user对象生成payload:jwt_payload_handler(user) => payload
            #       from rest_framework_jwt.serializers import jwt_payload_handler
            # 3)通过payload签发token:jwt_encode_handler(payload) => token
            #       from rest_framework_jwt.serializers import jwt_encode_handler

            校验token

            源码入口
            # 前提:访问一个配置了jwt认证规则的视图类,就需要提交认证字符串token,在认证类中完成token的校验
            
            # 1)rest_framework_jwt.authentication.JSONWebTokenAuthentication 的 父类 BaseJSONWebTokenAuthentication 的 authenticate 方法
            #       请求头拿认证信息jwt-token => 通过反爬小规则确定有用的token => payload => user
            核心源码:rest_framework_jwt.authentication.BaseJSONWebTokenAuthentication的authenticate(self, request)方法
            def authenticate(self, request):
                """
                Returns a two-tuple of `User` and token if a valid signature has been
                supplied using JWT-based authentication.  Otherwise returns `None`.
                """
                # 带有反爬小规则的获取token:前台必须按 "jwt token字符串" 方式提交
                # 校验user第1步:从请求头 HTTP_AUTHORIZATION 中拿token,并提取
                jwt_value = self.get_jwt_value(request)
                # 游客
                if jwt_value is None:
                    return None
                # 校验
                try:
                    # 校验user第2步:token => payload
                    payload = jwt_decode_handler(jwt_value)
                except jwt.ExpiredSignature:
                    msg = _('Signature has expired.')
                    raise exceptions.AuthenticationFailed(msg)
                except jwt.DecodeError:
                    msg = _('Error decoding signature.')
                    raise exceptions.AuthenticationFailed(msg)
                except jwt.InvalidTokenError:
                    raise exceptions.AuthenticationFailed()
                # 校验user第3步:token => payload
                user = self.authenticate_credentials(payload)
            
                return (user, jwt_value)
            手动校验token逻辑
            # 1)从请求头中获取token
            # 2)根据token解析出payload:jwt_decode_handler(token) => payloay
            #       from rest_framework_jwt.authentication import jwt_decode_handler
            # 3)根据payload解析出user:self.authenticate_credentials(payload) => user
            #       继承drf-jwt的BaseJSONWebTokenAuthentication,拿到父级的authenticate_credentials方法

            案例:实现多方式登陆签发token

            models.py
            from django.db import models
            
            from django.contrib.auth.models import AbstractUser
            class User(AbstractUser):
                mobile = models.CharField(max_length=11, unique=True)
            
                class Meta:
                    db_table = 'api_user'
                    verbose_name = '用户表'
                    verbose_name_plural = verbose_name
            
                def __str__(self):
                    return self.username
            serializers.py
            from rest_framework import serializers
            from . import models
            import re
            
            # 拿到前台token的两个函数: user => payload => token
            # from rest_framework_jwt.settings import api_settings
            # jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            # jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            from rest_framework_jwt.serializers import jwt_payload_handler
            from rest_framework_jwt.serializers import jwt_encode_handler
            
            
            # 1) 前台提交多种登录信息都采用一个key,所以后台可以自定义反序列化字段进行对应
            # 2) 序列化类要处理序列化与反序列化,要在fields中设置model绑定的Model类所有使用到的字段
            # 3) 区分序列化字段与反序列化字段 read_only | write_only
            # 4) 在自定义校验规则中(局部钩子、全局钩子)校验数据是否合法、确定登录的用户、根据用户签发token
            # 5) 将登录的用户与签发的token保存在序列化类对象中
            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 = {
                        'username': {
                            'read_only': True
                        },
                        'mobile': {
                            'read_only': True
                        },
                        'email': {
                            'read_only': True
                        },
                    }
            
                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(r'1[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()
            
                    # 签发:得到登录用户,签发token并存储在实例化对象中
                    if user_obj and user_obj.check_password(pwd):
                        # 签发token,将token存放到 实例化类对象的token 名字中
                        payload = jwt_payload_handler(user_obj)
                        token = jwt_encode_handler(payload)
                        # 将当前用户与签发的token都保存在序列化对象中
                        self.user = user_obj
                        self.token = token
                        return attrs
            
                    raise serializers.ValidationError({'data': '数据有误'})
            views.py
            #实现多方式登陆签发token:账号、手机号、邮箱等登陆
            # 1) 禁用认证与权限组件
            # 2) 拿到前台登录信息,交给序列化类
            # 3) 序列化类校验得到登录用户与token存放在序列化对象中
            # 4) 取出登录用户与token返回给前台
            import re
            from . import serializers, models
            from utils.response import APIResponse
            
            from rest_framework_jwt.serializers import jwt_payload_handler
            from rest_framework_jwt.serializers import jwt_encode_handler
            
            class LoginAPIView(APIView):
                # 1) 禁用认证与权限组件
                authentication_classes = []
                permission_classes = []
                def post(self, request, *args, **kwargs):
                    # 2) 拿到前台登录信息,交给序列化类,规则:账号用usr传,密码用pwd传
                    user_ser = serializers.UserModelSerializer(data=request.data)
                    # 3) 序列化类校验得到登录用户与token存放在序列化对象中
                    user_ser.is_valid(raise_exception=True)
                    # 4) 取出登录用户与token返回给前台
                    return APIResponse(token=user_ser.token, results=serializers.UserModelSerializer(user_ser.user).data)
            
                # "一根筋" 思考方式:所有逻辑都在视图类中处理
                def my_post(self, request, *args, **kwargs):
                    usr = request.data.get('usr')
                    pwd = request.data.get('pwd')
                    if re.match(r'[email protected]+', usr):
                        user_query = models.User.objects.filter(email=usr)
                    elif re.match(r'1[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):
                        payload = jwt_payload_handler(user_obj)
                        token = jwt_encode_handler(payload)
                        return APIResponse(results={'username': user_obj.username}, token=token)
                    return APIResponse(data_msg='不可控错误')

            案例:自定义认证反爬规则的认证类

            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 = jwt_decode_handler(token)
                    except jwt.ExpiredSignature:
                        raise AuthenticationFailed('token已过期')
                    except:
                        raise AuthenticationFailed('非法用户')
                    # payload => user
                    user = self.authenticate_credentials(payload)
            
                    return (user, token)
            
                # 自定义校验规则:auth token jwt,auth为前盐,jwt为后盐
                def parse_jwt_token(self, jwt_token):
                    tokens = jwt_token.split()
                    if len(tokens) != 3 or tokens[0].lower() != 'auth' or tokens[2].lower() != 'jwt':
                        return None
                    return tokens[1]
            views.py
            from rest_framework.views import APIView
            from utils.response import APIResponse
            # 必须登录后才能访问 - 通过了认证权限组件
            from rest_framework.permissions import IsAuthenticated
            # 自定义jwt校验规则
            from .authentications import JWTAuthentication
            class UserDetail(APIView):
                authentication_classes = [JWTAuthentication]
                permission_classes = [IsAuthenticated]
                def get(self, request, *args, **kwargs):
                    return APIResponse(results={'username': request.user.username})

            admin使用自定义User表:新增用户密码密文

            from django.contrib import admin
            from . import models
            
            # 自定义User表,admin后台管理,采用密文密码
            from django.contrib.auth.admin import UserAdmin
            
            class MyUserAdmin(UserAdmin):
                add_fieldsets = (
                    (None, {
                        'classes': ('wide',),
                        'fields': ('username', 'password1', 'password2', 'mobile', 'email'),
                    }),
                )
            
            admin.site.register(models.User, MyUserAdmin)

            群查接口各种筛选组件数据准备

            models.py
            class Car(models.Model):
                name = models.CharField(max_length=16, unique=True, verbose_name='车名')
                price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
                brand = models.CharField(max_length=16, verbose_name='品牌')
            
                class Meta:
                    db_table = 'api_car'
                    verbose_name = '汽车表'
                    verbose_name_plural = verbose_name
            
                def __str__(self):
                    return self.name
            admin.py
            admin.site.register(models.Car)
            serializers.py
            class CarModelSerializer(serializers.ModelSerializer):
                class Meta:
                    model = models.Car
                    fields = ['name', 'price', 'brand']
            views.py
            # Car的群查接口
            from rest_framework.generics import ListAPIView
            
            class CarListAPIView(ListAPIView):
                queryset = models.Car.objects.all()
                serializer_class = serializers.CarModelSerializer
            urls.py
            url(r'^cars/$', views.CarListAPIView.as_view()),

            drf搜索过滤组件

            views.py
            from rest_framework.generics import ListAPIView
            
            # 第一步:drf的SearchFilter - 搜索过滤
            from rest_framework.filters import SearchFilter
            
            class CarListAPIView(ListAPIView):
                queryset = models.Car.objects.all()
                serializer_class = serializers.CarModelSerializer
            
                # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
                filter_backends = [SearchFilter]
            
                # 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
                search_fields = ['name', 'price']
                # eg:/cars/?search=1,name和price中包含1的数据都会被查询出

            drf排序过滤组件

            views.py
            from rest_framework.generics import ListAPIView
            
            # 第一步:drf的OrderingFilter - 排序过滤
            from rest_framework.filters import OrderingFilter
            
            class CarListAPIView(ListAPIView):
                queryset = models.Car.objects.all()
                serializer_class = serializers.CarModelSerializer
            
                # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
                filter_backends = [OrderingFilter]
            
                # 第三步:OrderingFilter过滤类依赖的过滤条件 => 接口:/cars/?ordering=...
                ordering_fields = ['pk', 'price']
                # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序

            drf基础分页组件

            pahenations.py
            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'
                # 用户自定义一页显示的条数最大限制:数值超过5也只显示5条
                max_page_size = 5
            views.py
            from rest_framework.generics import ListAPIView
            
            class CarListAPIView(ListAPIView):
                # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
                queryset = models.Car.objects.all()
                serializer_class = serializers.CarModelSerializer
                
                # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
                pagination_class = pagenations.MyPageNumberPagination
            相关文章
            相关标签/搜索
            每日一句
              每一个你不满意的现在,都有一个你没有努力的曾经。
            公众号推荐
               一个历史类的公众号,欢迎关注
            一两拨千金
            中彩堂zzyz,ccus时来棋牌游戏下载-时来棋牌游戏平台app最新版下载 和田县| 侯马市| 肇源县| 长乐市| 西城区| 邵阳县| 武宁县| 怀仁县| 涞水县| 闻喜县| 嘉义市| 华亭县| 陈巴尔虎旗| 彭州市| 绥芬河市| 龙岩市| 雷州市| 广汉市| 武宁县| 红原县| 图木舒克市| 临洮县| 广平县| 凤阳县| 原阳县| 周口市| 九龙县| 石门县| 北海市| 江华| 巴塘县| 临武县| 同江市| 礼泉县| 金寨县| 托里县| 长兴县| 万年县| 潜江市| 北宁市| 韶山市| 崇义县| 潢川县| 嵊泗县| 泗洪县| 普陀区| 三原县| 黄浦区| 久治县| 东乌| 桐梓县| 子长县| 武强县| 贵州省| 汝南县| 鄂托克旗| 肇东市| 治多县| 乐都县| 会理县| 东兰县| 平远县| 桃园市| 平度市| 大埔县| 循化| 长兴县| 拉萨市| 阿尔山市| 通许县| 宁陕县| 林周县| 镇巴县| 永寿县| 南溪县| 嵊泗县| 元江| 长葛市| 新竹市| 滦南县| 马鞍山市| 改则县| 抚宁县| 芜湖市| 乌拉特后旗| 永嘉县| 万安县| 霸州市| 渭南市| 仙游县| 桦川县| 贺州市| 哈尔滨市| 金塔县| 怀柔区| 江山市| 揭阳市| 吴堡县| 砚山县| 江川县| 镇巴县| 汉川市| 营口市| 务川| 苗栗市| 南乐县| 阿克苏市| 仁怀市| 奉化市| 理塘县| 托里县| 霍林郭勒市| 桐庐县| 嘉定区| 茌平县| 武安市| 肃宁县| 成都市| 青田县| 拉孜县| 甘孜县| 额尔古纳市| 武功县| 鄯善县| 绥化市| 耒阳市| 宁德市| 湖南省| 潍坊市| 南京市| 宁国市| 阿巴嘎旗| 左云县| 弥勒县| 新蔡县| 拜城县| 江山市| 普宁市| 巩留县| 慈溪市| 凌云县| 平凉市| 白银市| 平凉市| 邻水| 鄂托克前旗| 涿鹿县| 景泰县| 巴楚县| 东乡族自治县| 博爱县| 涿州市| 舞钢市| 广东省| 连州市| 大荔县| 朝阳区| 化隆| 玉田县| 深水埗区| 叶城县| 石泉县| 阳朔县| 温州市| 青龙| 博客| 宁波市| 沈丘县| 广西| 太白县| 巴彦淖尔市| 青神县| 彭阳县| 通道| 红原县| 胶南市| 宁波市| 公主岭市| 南城县| 长治市| 安康市| 宁德市| 清苑县| 内乡县| 邵阳县| 潼南县| 古浪县| 昌黎县| 宁化县| 太湖县| 临猗县| 鄯善县| 会同县| 朝阳区| 蒲江县| 襄汾县| 东安县| 通许县| 龙胜| 泾阳县| 大宁县| 华安县| 宜宾市| 水城县| 辽阳县| 晋中市| 西和县| 宜宾县| 吉首市| 德庆县| 信阳市| 庄河市| 疏附县| 宕昌县| 山阴县| 衡水市| 崇义县| 佛教| 绥德县| 安新县| 陵水| 卫辉市| 太湖县| 阿坝| 清水河县| 芜湖市| 东乡族自治县| 田林县| 旅游| 武清区| 伊川县| 平湖市| 澄江县| 台湾省| 吉安市| 襄樊市| 新余市| 武平县| 故城县| 稷山县| 长汀县| 锡林郭勒盟| 金坛市| 禄劝| 木兰县| 奇台县| 任丘市| 南木林县| 新宁县| 砚山县| 嘉黎县| 延庆县| 望都县| 高碑店市| 鄢陵县| 兰溪市| 广丰县| 维西| 太仓市| 宁夏| 和田市| 东乌珠穆沁旗| 静宁县| 曲沃县| 休宁县| 岳阳市| 丁青县| 顺义区| 泽州县| 磐石市| 万荣县| 宜昌市| 包头市| 庆城县| 临洮县| 班戈县| 原阳县| 天水市| 霍山县| 商洛市| 阿拉尔市| 开远市| 外汇| 天峨县| 江城| 老河口市| 龙陵县| 九龙县| 通山县| 阳信县| 高密市| 上饶县| 中西区| 孟州市| 凤山县| 泽普县| 浙江省| 邵阳县| 增城市| 麻栗坡县| 嘉定区| 浦东新区| 府谷县| 革吉县| 会宁县| 年辖:市辖区| 陆川县| 高淳县| 宜良县| 凤台县| 富阳市| 遵化市| 石河子市| 乐至县| 扶余县| 新丰县| 雷山县| 正宁县| 离岛区| 洛隆县| 刚察县| 且末县| 贺兰县| 宣汉县| 长泰县| 图木舒克市| 葫芦岛市| 孟连| 佛学| 双城市| 铁岭县| 建瓯市| 平潭县| 聊城市| 陆丰市| 楚雄市| 云阳县| 普格县| 青川县| 凭祥市| 嘉善县| 赫章县| 吕梁市| 德格县| 东海县| 沾益县| 保山市| 陆良县| 荃湾区| 平泉县| 安图县| 临沭县| 孝感市| 郯城县| 胶州市| 莱州市| 安吉县| 台南县| 新建县| 台湾省| 上高县| 唐山市| 获嘉县| 色达县| 永寿县| 德兴市| 水富县| 历史| 城口县| 仙桃市| 滕州市| 济南市| 涿州市| 长治市| 长武县| 江津市| 赣州市| 东城区| 礼泉县| 峨山| 介休市| 梨树县| 商水县| 浦县| 南昌市| 灵丘县| 山阳县| 自治县| 邹平县| 武安市| 广宁县| 大名县| 江陵县| 扎兰屯市| 沭阳县| 大新县| 肥乡县| 荔浦县| 土默特右旗| 彝良县| 靖边县| 资中县| 互助| 贡山| 资中县| 芜湖县| 巴楚县| 玛沁县| 恩平市| 大庆市| 凤翔县| 松溪县| 阜康市| 平顺县| 仙桃市| 澄城县| 石狮市| 驻马店市| 任丘市| 页游| 青神县| 博罗县| 青浦区| 五指山市| 清涧县| 惠安县| 新闻| 牡丹江市| 南阳市| 雷山县| 栾城县| 温宿县| 平利县| 卓尼县| 黄大仙区| 遂平县| 砀山县| 汾阳市| 洛扎县| 台前县| 河北省| 钟山县| 河津市| 蓬安县| 侯马市| 资兴市| 讷河市| 云梦县| 长白| 密云县| 岢岚县| 肃北| 香港| 张家口市| 涟源市| 林口县| 西乌| 蓬溪县| 江山市| 肃北| 米易县| 苗栗市| 大余县| 开江县| 江华| 虎林市| 民县| 静安区| 拜泉县| 永泰县| 南通市| 清水河县| 洞口县| 延寿县| 盐山县| 蒲江县| 库伦旗| 华宁县| 新河县| 湖南省| 海城市| 讷河市| 荥阳市| 竹山县| 辰溪县| 定州市| 灯塔市| 大连市| 藁城市| 和硕县| 涪陵区| 潍坊市| 台东县| 陆河县| 曲阳县| 大渡口区| 正宁县| 长治市| 醴陵市| 元朗区| 葫芦岛市| 佛学| 定襄县| 石林| 察雅县| 安陆市| 万安县| 尚义县| 灵寿县| 尖扎县| 冕宁县| 无为县| 洛隆县| 突泉县| 桑植县| 安西县| 阿拉善左旗| 临夏市| 文化| 麻江县| 拉孜县| 天津市| 东城区| 洮南市| 双鸭山市| 盐津县| 溧阳市| 黔西| 衡阳市| 铜陵市| 富源县| 锡林郭勒盟| 阿城市| 宁海县| 青田县| 常德市| 紫金县| 宜州市| 马山县| 定南县| 达拉特旗| 灵宝市| 宝应县| 平南县| 莆田市| 天等县| 莱西市| 乐东| 盘山县| 济阳县| 枣阳市| 汶上县| 武定县| 莎车县| 车致| 财经| 汕尾市| 洪湖市| 济阳县| 于都县| 阿巴嘎旗| 湛江市| 新巴尔虎右旗| 兴和县| 泾源县| 新乡县| 宜兰市| 靖西县| 突泉县| 思茅市| 浑源县| 岳西县| 南京市| 木里| 峨山| 富平县| 营山县| 咸宁市| 内丘县| 盐源县| 临邑县| 文登市| 山西省| 博罗县| 和田县| 茂名市| 清徐县| 集贤县| 上思县| 武川县| 德安县| 阜宁县| 横峰县| 来安县| 东乌珠穆沁旗| 蓬莱市| 本溪| 奉节县| 双城市| 泽库县| 澄迈县| 进贤县| 贵州省| 同江市| 大渡口区| 鹤庆县| 龙泉市| 桂平市| 隆子县| 高台县| 天镇县| 聂荣县| 乐至县| 项城市| 九江县| http://jx1870frazev.fun http://www.hz0j4r4vo.fun http://www.jx1870flyv.fun http://www.jx1870leadv.fun http://m.hz0j3r3vo.fun http://www.jx1870fruitv.fun http://m.hz0j2r6vo.fun http://www.jx1870handv.fun http://wap.hz0j1r8vo.fun http://www.jx1870fearv.fun http://wap.jx1870gazev.fun http://www.jx1870greenv.fun http://www.hz0j2r2vo.fun http://m.jx1870exercisev.fun http://www.jx1870gearv.fun http://www.jx1870fundv.fun http://jx1870gradev.fun http://wap.jx1870headv.fun