22 发送短信接口+短信登录接口

一、 发送短信接口

user/views.py

#django的缓存===直接用就可以了===默认缓存到内存中
from django.core.cache import cache
class
UserView(ViewSet): @action(methods=['GET'], detail=False, ) def send_sms(self, request): phone = request.query_params.get('phone') sms_code = gen_code()
#需要保存起来,以后还能拿到===》放到缓存中
# res = send_sms_v2(phone, sms_code) res = send_sms_v3(phone, sms_code) print(sms_code) if res: return APIResponse() else: return APIResponse(code=101, msg='发送失败,请稍后再试')

 补充保存code:

 

 

 

 二、短信登录接口

# 前端传入(post):{mobile:1892322345,code:1234}

 

user/serializer.py

class MobileSerializer(serializers.ModelSerializer):
    # code字段不是表的字段,所以需要重写
    code = serializers.CharField(max_length=5, min_length=4)
    mobile = serializers.CharField()

    class Meta:
        model = User
        fields = ['mobile', 'code']

    def validate(self, attrs):

        # 1 校验code是否正确
        self._check_code(attrs)
        # 2 根据手机号查到用户
        user = self._get_user_by_mobile(attrs)
        # 3 签发token
        token = self._get_token(user)
        # 4 把给view用的放到context中
        self.context['token'] = token
        self.context['username'] = user.username
        # self.context['icon']=user.icon # icon的有点问题
        # 这个地址是服务端地址,服务端地址从request对象中可以取出request.META['HTTP_HOST']
        request = self.context.get('request')
        self.context['icon'] = 'http://%s/media/' % request.META['HTTP_HOST'] + str(user.icon)
        return attrs

    def _check_code(self, attrs):
        code = attrs.get('code')
        # 取出该手机号对应的code
        mobile = attrs.get('mobile')
        old_code = cache.get(settings.SMS_CODE_CACHE % mobile)
        # cache.set(settings.SMS_CODE_CACHE % mobile,'')
        # 如果是调试模式,有个万能验证码
        if not old_code == code:
            raise ValidationError('验证码错误')

    def _get_user_by_mobile(self, attrs):
        mobile = attrs.get('mobile')
        user = User.objects.filter(mobile=mobile).first()
        if user:
            return user
        else:
            raise ValidationError('用户不存在')

    def _get_token(self, user):
        # 根据user获取payload
        payload = jwt_payload_handler(user)
        # 根据payload得到token
        token = jwt_encode_handler(payload);
        return token

user/views.py

class LoginView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = LoginSerializer

    def get_serializer_class(self):
        print(self.action)
        if self.action == 'mul_login':
            return self.serializer_class
        else:
            return MobileSerializer

    @action(methods=['POST'], detail=False, )  # user/login/mobile_login
    def mobile_login(self, request):
        return self._login(request)

    def _login(self, request):
        try:
            # 方式一
            # ser=MobileSerializer(data=request.data, context={'request': request})
            # 方式二(重写get_serializer_class)
            ser = self.get_serializer(data=request.data, context={'request': request})

            ser.is_valid(raise_exception=True)  # 走序列化类的字段自己的规则,局部钩子和全局钩子
            token = ser.context.get('token')
            username = ser.context.get('username')
            icon = ser.context.get('icon')
        except Exception as e:
            raise APIException(str(e))
        return APIResponse(token=token, username=username, icon=icon)

#settings/common_settings.py

SMS_CODE_CACHE='sms_code_mobile_%s'

 

 cache的使用

from django.core.cache import cache

cache.set(key,value)
cache.get(key)

 

 

posted @ 2022-02-24 19:17  甜甜de微笑  阅读(116)  评论(0编辑  收藏  举报