手機接口

手機號驗證

導包
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')
        # 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:  # 有異常表明未註冊
            # log.info('手機未註冊')
            return Response({
                'status': 0,
                'msg': '手機未註冊',
            })
        # log.info('手機已註冊')
        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
# 短信模板 [測試階段只能爲1]
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))
        # redis緩存驗證碼
        cache.set(mobile, '%s_%s' % (mobile, code), constant.SMS_EXPIRE_TIME)
        # 發送驗證碼
        try:
            # send_template_sms("接受短信的手機號碼",["短信驗證碼", "短信有效期"], 短信模板ID)
            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")

        # 取出服務器驗證碼:redis緩存的
        old_sms = cache.get(mobile)

        # 校驗驗證碼:驗證碼的過時時間 redis與短信提醒方 統一了
        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()),
接口:用能夠收到短信的電話
# post請求
http://api.luffy.cn:8000/user/register/mobile/
# 數據
{
    "mobile": "13355667788",
    "password": "111111"
    "sms": "325817",
}

短信登陸

二次封裝手動簽發JWT:user/utls.py
# 二次封裝手動簽發jwt
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()),
接口:用能夠收到短信的電話
# post請求
http://api.luffy.cn:8000/user/login/mobile/
# 數據
{
    "mobile": "13355667788",
    "sms": "325817",
}
相關文章
相關標籤/搜索