03-06 短信登录接口

urls.py
router = SimpleRouter()
router.register('', views.LoginAPIView, 'login')
urlpatterns = [
    path('', include(router.urls)),
]
serializers.py
class BaseMethod(serializers.ModelSerializer):
    def _sign_token(self, user):
        """签发token"""
        import jwt
        import datetime
        from django.conf import settings
        headers = {
            'typ': 'jwt',
            'alg': 'HS256',
        }
        payload = {
            'user_id': user.pk,
            'username': user.username,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=7),
        }
        # 盐
        slat = settings.SECRET_KEY
        token = jwt.encode(payload, key=slat, headers=headers)
        return token

    def validate(self, attrs):
        user = self._get_user(attrs)
        # 签发token
        token = self._sign_token(user)

        self.context['token'] = token
        self.context['user'] = user
        return attrs

    def _get_user(self, *args, **kwargs):
        raise NotImplementedError("._get_user() must be overridden.")


class CodeUserModelSerializer(BaseMethod):
    code = serializers.CharField()

    class Meta:
        model = models.User
        fields = ('telephone', 'code')

    def _get_user(self, attrs):
        """
        校验获取用户对象:
        1. 判断用户手机号码是否符合格式
        2. 判断用户手机号码是否存在数据中
        3. 通过手机号码从缓存中获取用户的正确验证码
        """
        from django.core.cache import cache
        from django.conf import settings

        telephone = attrs.get('telephone')
        code = attrs.get('code')
        if re.match(r'1[3-9][0-9]{9}$', telephone):
            user = models.User.objects.filter(telephone=telephone).first()
            utils.log.info(user)
            if user:
                # PHONE_CODE_KEY
                telephone_key = settings.PHONE_CODE_KEY % telephone
                cache_code = cache.get(telephone_key)
                if code == cache_code:
                    # 注意: 用户登录以后, 验证码留在缓存中已经没有意义了!!
                    cache.set(telephone_key, '')
                    return user
                raise ValidationError('验证码过期, 请重新发送!')
            raise ValidationError("手机号码不存在!")
        raise ValidationError('手机号码格式错误!')
views.py
class LoginAPIView(ViewSet):
    ...

    @action(methods=('post',), detail=False)
    def code_login(self, request, *args, **kwargs):
        ser = serializer.CodeUserModelSerializer(data=request.data)
        ser.is_valid(raise_exception=True)

        token = ser.context['token']
        user = ser.context['user']
        return utils.APIResponse(token=token, username=user.username)
posted @ 2020-07-23 19:44  给你加马桶唱疏通  阅读(99)  评论(0编辑  收藏  举报