19-短信登录接口
短信登录接口
urls.py
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from . import views
router = SimpleRouter()
router.register('', views.SendSmsView, 'send') # 此处第一个参数不要加上,因为视图类中使用了actions,会把该视图名添加进来
urlpatterns = [
path('', include(router.urls)),
]
serializer.py
# 验证码登录
class Codeserializers(serializers.ModelSerializer):
code = serializers.CharField() # code字段在数据库中不存在,所以需要自己定义
class Meta:
model = models.User
fields = ['telephone', 'code']
# 验证码登录+token签发
def validate(self, attrs):
user = self._get_user(attrs)
token = self._get_token(user)
self.context['token'] = token
self.context['user'] = user
return attrs
# 验证码登录逻辑
def _get_user(self, attrs):
telephone = attrs.get('telephone')
code = attrs.get('code') # 此处也还有个问题
# 先校验验证码是否匹配
cache_code = cache.get(settings.PYTHON_CACHE_KEY.format(telephone))
print("前端获取:", code, type(code))
print("缓存获取:", cache_code, type(cache_code))
# if cache_code == code: 此处是因为没有腾讯短信,所以就简单一点,手动发送验证码
if cache_code == code:
# 验证码校验通过
if re.match('^1[3-9][0-9]{9}$', telephone):
user = models.User.objects.filter(telephone=telephone).first()
if user: # 验证码和手机号码都正确,返回当前用户对象
# 代码能执行到此处,就说明一切信息都正确,就将cache_code资源置空
cache.set(settings.PYTHON_CACHE_KEY.format(telephone, ), "")
# 返回当前对象
return user
else:
raise ValidationError('验证码正确,手机号码错误!')
else:
raise ValidationError('手机号码格式错误!')
else:
raise ValidationError('验证码错误!')
# 签发token
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 SendSmsView(ViewSet):
throttle_classes = (SmsThrottling,)
# 验证登录视图接口
@action(methods=('POST',), detail=False)
def code_login(self, request, *args, **kwargs):
ser = serializer.Codeserializers(data=request.data)
if ser.is_valid():
token = ser.context['token']
username = ser.context['user'].username
return APIResponse(token=token, username=username)
else:
return APIResponse(code=0, msg='Error', result=ser.errors)