手机号验证
导包
import logging
log = logging.getLogger('django')
import re
import random
from .models import User
from settings import constant
from libs.yuntongxun.sms import CCP
from django.core.cache import cache
from .utils import get_jwt_by_user
from .utils import SMSRateThrottle
from rest_framework.response import Response
from .serializers import UserModelSerializer
视图:user/views.py
class CheckMobileAPIView(APIView):
def get(self, request, *args, **kwargs):
mobile = request.query_params.get('mobile')
if not mobile:
return Response({
'status': 2,
'msg': '缺失手机号',
})
if not re.match(r'^1[3-9]\d{9}$', mobile):
return Response({
'status': 2,
'msg': '手机号有误',
})
try:
User.objects.get(mobile=mobile)
except:
return Response({
'status': 0,
'msg': '手机未注册',
})
return Response({
'status': 1,
'msg': '手机已注册',
})
路由:user/urls.py
path("mobile/", views.CheckMobileAPIView.as_view()),
接口
http://api.luffy.cn:8000/user/mobile/?mobile=13355667788
获取验证码
依赖
pip install django-redis
短信频率组件:user/utils.py
from rest_framework.throttling import SimpleRateThrottle
class SMSRateThrottle(SimpleRateThrottle):
scope = 'sms'
def get_cache_key(self, request, view):
mobile = request.query_params.get('mobile')
return "Throttle:%s" % mobile
配置:settings/dev.py
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
}
}
}
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'sms': '1/m'
},
}
配置常量:settings/constant.py
SMS_EXPIRE_TIME = 300
SMS_TEMPLATE_ID = 1
视图:user/views.py
class SMSAPIView(APIView):
throttle_classes = [SMSRateThrottle]
def get(self, request, *args, **kwargs):
""" 发送短信 """
mobile = request.query_params.get('mobile')
if not re.match(r'^1[3-9]\d{9}$', mobile):
return Response('手机号有误')
code = ''
for i in range(6):
code += str(random.randint(0, 9))
cache.set(mobile, '%s_%s' % (mobile, code), constant.SMS_EXPIRE_TIME)
try:
result = CCP().send_template_sms(mobile, [code, constant.SMS_EXPIRE_TIME // 60], constant.SMS_TEMPLATE_ID)
if result == -1:
log.error("发送短信出错!手机号:%s" % mobile)
return Response({'result': '短信发送失败'})
except:
log.error("发送短信出错!")
return Response({'result': '短信发送失败'})
return Response({'result': '短信发送成功'})
路由
path('sms/', views.SMSAPIView.as_view()),
接口:用可以收到短信的电话
http://api.luffy.cn:8000/user/sms/?mobile=13355667788
短信注册
视图:user/views.py
class RegisterCheckSMSAPIView(APIView):
def post(self, request, *args, **kwargs):
"""验证码注册"""
mobile = request.data.get("mobile")
password = request.data.get("password")
sms = request.data.get("sms")
old_sms = cache.get(mobile)
if sms != old_sms:
return Response({
'status': 1,
'msg': '注册失败',
})
try:
user = User.objects.create_user(mobile=mobile, password=password, username=mobile)
except:
return Response({
'status': 1,
'msg': '注册失败',
})
return Response({
'status': 0,
'msg': '注册成功',
"user": UserModelSerializer(user).data
})
路由
path('register/mobile/', views.RegisterCheckSMSAPIView.as_view()),
接口:用可以收到短信的电话
http://api.luffy.cn:8000/user/register/mobile/
{
"mobile": "13355667788",
"password": "111111"
"sms": "325817",
}
短信登录
二次封装手动签发JWT:user/utls.py
def get_jwt_by_user(user):
from rest_framework_jwt.settings import api_settings
try:
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token
except Exception:
return None
视图:user/views.py
class LoginCheckSMSAPIView(APIView):
def post(self, request, *args, **kwargs):
mobile = request.data.get('mobile')
sms = request.data.get('sms')
old_sms = cache.get(mobile)
if sms != old_sms:
return Response({'msg': '登陆失败'})
try:
user = User.objects.get(mobile=mobile)
except User.DoesNotExist:
return Response({'msg': '登陆失败'})
return Response({
'token': get_jwt_by_user(user),
'user': UserModelSerializers(user).data
})
路由
path('login/mobile/', views.LoginCheckSMSAPIView.as_view()),
接口:用可以收到短信的电话
http://api.luffy.cn:8000/user/login/mobile/
{
"mobile": "13355667788",
"sms": "325817",
}