注册
- 用户输入手机号, 前端通过js代码自动向校验手机号接口发送get请求
- 校验手机号是否已注册
- 如果手机号未注册, 则允许点击发送验证码按钮向发送验证码接口发送get请求
- 继续输入验证码和密码, 向手机号注册接口发送post请求
- 校验手机号和验证码, 校验通过后将新注册的用户信息保存到数据库中
校验手机号接口
'''
# ...luffyapiluffyapiappsuserurls.py
...
urlpatterns = [
...
path('mobile/check', views.CheckMobileAPIView.as_view()),
]
# ...luffyapiluffyapiappsuserviews.py
...
class CheckMobileAPIView(APIView):
def get(self, request, *args, **kwargs):
mobile = request.query_params.get('mobile')
if not mobile:
return Response(data={'code': 1, 'detail': 'mobile字段必须提供'}, status=400)
if not re.match(r'^1[3-9][0-9]{9}$', mobile):
return Response(data={'code': 1, 'detail': '手机号格式有误'}, status=400)
try:
models.User.objects.get(mobile=mobile, is_active=True)
return Response(data={'code': 2, 'msg': '手机号已注册'})
except:
return Response(data={'code': 0, 'msg': '手机号未注册'})
'''
手机号注册接口
'''
# ...luffyapiluffyapiappsuserurls.py
...
urlpatterns = [
...
path('mobile/register/', views.MobileRegisterAPIView.as_view()),
]
# ...luffyapiluffyapiappsuserviews.py
...
class MobileRegisterAPIView(CreateAPIView):
serializer_class = my_serializers.MobileRegisterSerializer
def create(self, request, *args, **kwargs):
response = super().create(request, *args, **kwargs)
response.data.pop('password')
return response
# ...luffyapiluffyapiappsusermy_serializers.py
...
class MobileRegisterSerializer(serializers.Serializer):
code = serializers.CharField(write_only=True, min_length=6, max_length=6)
mobile = serializers.CharField()
password = serializers.CharField(min_length=8)
def validate(self, attrs):
mobile = attrs.get('mobile')
code = attrs.pop('code')
if not re.match(r'^1[3-9][0-9]{9}$', mobile):
raise serializers.ValidationError('手机号格式有误')
if not code.isdigit(): # 校验验证码是否为纯数字, 否则直接抛错, 减少数缓存io
raise serializers.ValidationError('验证码不为纯数字')
cache_code = cache.get(settings.CODE_CACHE_FORMAT % mobile) # 获取服务器缓存的验证码
if code != cache_code:
raise serializers.ValidationError('验证码有误')
attrs['username'] = mobile # 将手机号设为用户名
return attrs
def create(self, validated_data):
instance = models.User.objects.create_user(**validated_data) # 通过User表绑定的auth模块提供的create_user方法将用户密码以密文形式存入数据库
cache.delete(settings.CODE_CACHE_FORMAT % validated_data.get('mobile'))
return instance
'''
全局配置drf-jwt身份认证, 局部配置SendSmsAPIView类的频率认证
'''
# ...luffyapiluffyapisettingsdev_settings.py
...
REST_FRAMEWORK = {
...',
'DEFAULT_THROTTLE_RATES': {
'sms_code': '1/min'
},
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
],
}
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
# ...luffyapiluffyapiappsusermy_throttling.py
from rest_framework.throttling import SimpleRateThrottle
class CodeRateThrottle(SimpleRateThrottle):
scope = 'sms_code'
def get_cache_key(self, request, view):
mobile = request.query_params.get('mobile') or not request.data.get('mobile')
if not mobile:
return None
return self.cache_format % {
'scope': self.scope,
'ident': mobile
}
# ...luffyapiluffyapiappsuserviews.py
class SendSmsAPIView(APIView):
throttle_classes = [my_throttling.CodeRateThrottle, ]
...
'''
Vue操作Cookie
'''
1. 安装
vue-cookies: cnpm install vue-cookies
2. 配置
# ...luffycitysrcmain.js
import cookies from 'vue-cookies'
Vue.prototype.$cookies = cookies;
3. 使用
this.$cookies.set(key, value, exp) # exp为过期时间
this.$cookies.get(key)
this.$cookies.remove(key)
'''