zoukankan      html  css  js  c++  java
  • 短信登录接口

    后台

    urls.py
    path('mobile/login/', views.MobileLoginViewSet.as_view({'post': 'login'})),
    
    serializers.py
    import re
    from django.core.cache import cache
    class MobileLoginSerializer(serializers.ModelSerializer):
        # 覆盖
        mobile = serializers.CharField(required=True, write_only=True)
        # 自定义
        code = serializers.CharField(min_length=4, max_length=4, required=True, write_only=True)
        class Meta:
            model = models.User
            fields = ('id', 'username', 'icon', 'mobile', 'code')
            extra_kwargs = {
                'id': {
                    'read_only': True,
                },
                'username': {
                    'read_only': True,
                },
                'icon': {
                    'read_only': True,
                },
    
            }
    
        # 手机号格式校验(手机号是否存在校验规则自己考量)
        def validate_mobile(self, value):
            if not re.match(r'^1[3-9][0-9]{9}$', value):
                raise exceptions.ValidationError('mobile field error')
            return value
    
    
        def validate(self, attrs):
            # 验证码校验 - 需要验证码与手机号两者参与
            mobile = self._check_code(attrs)
            # 多方式得到user
            user = self._get_user(mobile)
            # user签发token
            token = self._get_token(user)
            # token用context属性携带给视图类
            self.context['token'] = token
            # 将登录用户对象直接传给视图
            self.context['user'] = user
            return attrs
    
        def _check_code(self, attrs):
            mobile = attrs.get('mobile')
            code = attrs.pop('code')
            old_code = cache.get(settings.SMS_CACHE_KEY % {'mobile': mobile})
            if code != old_code:
                raise exceptions.ValidationError({'code': 'double code error'})
            else:
                # 验证码的时效性:一旦验证码验证通过,代表改验证码已使用,需要立即失效
                # cache.set(settings.SMS_CACHE_KEY % {'mobile': mobile}, '', -1)
                pass
            return mobile
    
        def _get_user(self, mobile):
            try:
                return models.User.objects.get(mobile=mobile)
            except:
                raise exceptions.ValidationError({'mobile': 'user not exist'})
    
        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
    
    
    views.py
    class MobileLoginViewSet(ViewSet):
        # 局部禁用认证、权限组件
        authentication_classes = ()
        permission_classes = ()
    
        def login(self, request, *args, **kwargs):
            serializer = serializers.MobileLoginSerializer(data=request.data, context={'request': request})
            if serializer.is_valid():
                token = serializer.context.get('token')
                # 拿到登录用户,直接走序列化过程,将要返回给前台的数据直接序列化好给前台
                user = serializer.context.get('user')
                # 返回给前台的数据结果:id,username,icon,token
                result = serializers.MobileLoginSerializer(user, context={'request': request}).data
                result['token'] = token
    
                return APIResponse(result=result)
            return APIResponse(1, serializer.errors)
    
  • 相关阅读:
    使用python scrapy爬取知乎提问信息
    [java基础]一文理解java多线程必备的sychronized关键字,从此不再混淆!
    python scrapy 登录知乎过程
    python scrapy爬虫框架概念介绍(个人理解总结为一张图)
    【干货】一文理解Druid原理架构(时序数据库,不是ali的数据库连接池)
    2016年我所面试过的那些公司
    写在2017年1月
    分页pagination实现及其应用
    inconsistent line count calculation in projection snapshot
    来去匆匆
  • 原文地址:https://www.cnblogs.com/kai-/p/12403204.html
Copyright © 2011-2022 走看看