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}
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/
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)