注册登录页面修订-Python使用redis-手机验证接口-发送短信验证
登录页面修订
views.Login.vue
<template> <div class="login box"> <img src="@/assets/img/Loginbg.jpg" alt=""> <div class="login"> <div class="login-title"> <img src="@/assets/img/Logotitle.png" alt=""> <p>帮助有志向的年轻人通过努力学习获得体面的工作和生活!</p> </div> <div class="login_box"> <div class="title"> <span :class="{active: a0}" @click="changeLogin(0)">密码登录</span> <span :class="{active: a1}" @click="changeLogin(1)">短信登录</span> </div> <div class="inp" v-if="login_type==0"> <input v-model="username" type="text" placeholder="用户名 / 手机号码" class="user"> <input v-model="password" type="password" name="" class="pwd" placeholder="密码"> <div id="geetest1"></div> <div class="rember"> <p> <input id="checkbox" type="checkbox" class="no" v-model="remember"/> <span>记住密码</span> </p> <p>忘记密码</p> </div> <button class="login_btn" @click="loginAction">登录</button> <p class="go_login">没有账号 <router-link to="/register">立即注册</router-link></p> </div> <div class="inp" v-show="login_type==1"> <input v-model="mobile" type="text" placeholder="手机号码" class="user"> <div class="sms"> <input v-model="sms" type="text" placeholder="输入验证码" class="user"> <span class="sms_btn" @click="send_sms">{{sms_interval_tips}}</span> </div> <button class="login_btn" @click="loginMobile">登录</button> <p class="go_login">没有账号 <router-link to="/register">立即注册</router-link></p> </div> </div> </div> </div> </template> <script> export default { name: 'Login', data() { return { a0: 1, a1: 0, login_type: 0, username: "", password: "", remember: false, mobile: "", sms: "", is_send: false, // 是否在60s内发送了短信 sms_interval_tips: "获取验证码", } }, methods: { changeLogin(i) { this.login_type = i; if (i) { this.a0 = 0; this.a1 = 1; } else { this.a0 = 1; this.a1 = 0; } }, loginAction() { if (!this.username || !this.password) { return } this.$axios({ url: this.$settings.Host + 'user/login/', method: 'post', data: { 'username': this.username, 'password': this.password } }).then((response) => { // 判断用户是否要记住密码 window.console.log(">>>>", response.data); if (this.remember) { // 记住密码 sessionStorage.clear(); localStorage.token = response.data.token; localStorage.user_name = response.data.user.username; localStorage.user_mobile = response.data.user.mobile; } else { /// 没记住密码 localStorage.clear(); sessionStorage.token = response.data.token; sessionStorage.user_id = response.data.user.username; sessionStorage.user_name = response.data.user.mobile; } // 页面跳转 let _this = this; this.$alert("欢迎回来!", "登录成功!", { confirmButtonText: '确定', callback() { // 跳转页面 _this.$router.go(-1); // 返回上一页 // 进行制定的网站内部地址跳转 // this.$router.push("站内地址"); } }) }).catch((error) => { window.console.log('失败:', error); // 页面跳转 let _this = this; this.$alert("检查账号密码!", "登录失败!", { confirmButtonText: '确定', callback() { _this.username = ''; _this.password = ''; } }); }) }, send_sms() { // 发送短信 if (!/^1[3-9]\d{9}$/.test(this.mobile)) { this.$message({ message: "对不起!手机号码格式有误!" }); return false; } // 判断是否在60s内发送过短信 if (this.is_send) { this.$message({ message: "对不起,不能频繁发送短信验证!" }); return false; } // 请求发送短信 this.$axios({ url: this.$settings.Host + 'user/sms/', method: 'get', params: { mobile: this.mobile } }).then(response => { let msg = response.data.result this.$message({ message: msg, }); if (msg === '短信发送失败') return // 修改短信的发送状态 this.is_send = true; // 设置间隔时间60s let sms_interval_time = 60; // 设置短信发送间隔倒计时,.60s后把is_send改成false let timer = setInterval(() => { if (sms_interval_time <= 1) { clearInterval(timer); this.sms_interval_tips = "获取验证码"; this.is_send = false; // 重新回复点击发送功能的条件 } else { sms_interval_time -= 1; this.sms_interval_tips = `${sms_interval_time}秒后再次获取`; } }, 1000); }).catch(error => { this.$message({ message: error.response.data.result, }) }); }, loginMobile() { // 注册信息提交 if (!/^1[3-9]\d{9}$/.test(this.mobile)) { this.$message({ message: "对不起!手机号码格式有误!" }); return false; } if (this.sms.length < 1) { this.$message({ message: "短信验证码不能为空!" }); return false; } this.$axios({ url: this.$settings.Host + 'user/login/mobile/', method: 'post', data: { mobile: this.mobile, sms: this.sms } }).then(response => { let _this = this; let status = response.data.status; let msg = response.data.msg; _this.$message({ message: msg, onClose() { if (status == 0) { // 保存登录状态 sessionStorage.token = response.data.token; sessionStorage.user_name = response.data.user.username; // sessionStorage.user_mobile = response.data.user.mobile; // 跳转到主页 _this.$router.push('/'); } } }); }).catch(error => { this.$message({ message: error.response.data.result }); }) }, }, }; </script> <style scoped> .box { width: 100%; height: 100%; position: relative; overflow: hidden; } .box img { width: 100%; min-height: 100%; } .box .login { position: absolute; width: 500px; height: 400px; left: 0; margin: auto; right: 0; bottom: 0; top: -338px; } .login .login-title { width: 100%; text-align: center; padding-top: 20px; } .login-title img { width: 190px; height: auto; } .login-title p { font-family: PingFangSC-Regular; font-size: 18px; color: #fff; letter-spacing: .29px; padding-top: 10px; padding-bottom: 50px; } .login_box { width: 400px; height: auto; background: #fff; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5); border-radius: 4px; margin: 0 auto; padding-bottom: 40px; } .login_box .title { font-size: 20px; color: #9b9b9b; letter-spacing: .32px; border-bottom: 1px solid #e6e6e6; display: flex; justify-content: space-around; padding: 50px 60px 0 60px; margin-bottom: 20px; cursor: pointer; } .login_box .title span.active { color: #4a4a4a; border-bottom: 2px solid #84cc39; } .inp { width: 350px; margin: 0 auto; } .inp input { outline: 0; width: 100%; height: 45px; border-radius: 4px; border: 1px solid #d9d9d9; text-indent: 20px; font-size: 14px; background: #fff !important; } .inp input.user { margin-bottom: 16px; } .inp .rember { display: flex; justify-content: space-between; align-items: center; position: relative; margin-top: 10px; } .inp .rember p:first-of-type { font-size: 12px; color: #4a4a4a; letter-spacing: .19px; margin-left: 22px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; /*position: relative;*/ } .inp .rember p:nth-of-type(2) { font-size: 14px; color: #9b9b9b; letter-spacing: .19px; cursor: pointer; } .inp .rember input { outline: 0; width: 30px; height: 45px; border-radius: 4px; border: 1px solid #d9d9d9; text-indent: 20px; font-size: 14px; background: #fff !important; } .inp .rember p span { display: inline-block; font-size: 12px; width: 100px; /*position: absolute;*/ /*left: 20px;*/ } #geetest { margin-top: 20px; } .login_btn { width: 100%; height: 45px; background: #84cc39; border-radius: 5px; font-size: 16px; color: #fff; letter-spacing: .26px; margin-top: 30px; } .inp .go_login { text-align: center; font-size: 14px; color: #9b9b9b; letter-spacing: .26px; padding-top: 20px; } .inp .go_login a { color: #84cc39; cursor: pointer; } #get_code { border: 0; width: 120px; height: 30px; background-color: antiquewhite; outline: none; } #get_code:active { color: white; } #checkbox { width: 20px; height: 20px; } .sms { position: relative; } .sms .sms_btn { position: absolute; top: -12px; right: 0; bottom: 0; margin: auto; width: 130px; text-align: center; height: 24px; color: #ff7000; cursor: pointer; border-left: 1px solid #999; } </style>
注册页面修订
views.Register,vue
<template> <div class="box"> <img src="@/assets/img/Loginbg.jpg" alt=""> <div class="register"> <div class="register_box"> <div class="register-title">注册路飞学城</div> <div class="inp"> <input v-model="mobile" @blur="checkMobile" type="text" placeholder="手机号码" class="user"> <input v-model="password" type="password" placeholder="用户密码" class="user"> <div class="sms"> <input v-model="sms" type="text" placeholder="输入验证码" class="user"> <span class="sms_btn" @click="send_sms">{{sms_interval_tips}}</span> </div> <div id="geetest"></div> <button class="register_btn" @click="registerMobile">注册</button> <p class="go_login">已有账号 <router-link to="/login">直接登录</router-link> </p> </div> </div> </div> </div> </template> <script> export default { name: 'Register', data() { return { sms: "", mobile: "", password: "", is_send: false, // 是否在60s内发送了短信 sms_interval_tips: "获取验证码", } }, created() { }, methods: { checkMobile() { if (this.mobile.length < 1) { return false; } // 手机号码格式是否正确 if (!/^1[3-9]\d{9}$/.test(this.mobile)) { this.$message({ message: "对不起!手机号码格式有误!" }); return false; } // 验证手机号码是否已经注册了 // this.$axios.get(this.$settings.Host+"/users/mobile/"+this.mobile+"/"); this.$axios({ url: this.$settings.Host + 'user/mobile/', method: 'get', params: { mobile: this.mobile } }).then(response => { let data = response.data; window.console.log(data); if (data.status != 0) { this.$message({ message: "对不起!手机号码已经被注册!" }); return false; } else { this.$message({ message: "期待您加入我们!" }); } }).catch(error => { let data = error.response.data; this.$message({ message: data.message }) }) }, send_sms() { // 发送短信 if (!/^1[3-9]\d{9}$/.test(this.mobile)) { this.$message({ message: "对不起!手机号码格式有误!" }); return false; } // 判断是否在60s内发送过短信 if (this.is_send) { this.$message({ message: "对不起,不能频繁发送短信验证!" }); return false; } // 请求发送短信 this.$axios({ url: this.$settings.Host + 'user/sms/', method: 'get', params: { mobile: this.mobile } }).then(response => { this.$message({ message: response.data.result, }); // 修改短信的发送状态 this.is_send = true; // 设置间隔时间60s let sms_interval_time = 60; // 设置短信发送间隔倒计时,.60s后把is_send改成false let timer = setInterval(() => { if (sms_interval_time <= 1) { clearInterval(timer); this.sms_interval_tips = "获取验证码"; this.is_send = false; // 重新回复点击发送功能的条件 } else { sms_interval_time -= 1; this.sms_interval_tips = `${sms_interval_time}秒后再次获取`; } }, 1000); }).catch(error => { this.$message({ message: error.response.data.result, }) }); }, registerMobile() { // 注册信息提交 if (!/^1[3-9]\d{9}$/.test(this.mobile)) { this.$message({ message: "对不起!手机号码格式有误!" }); return false; } if (this.sms.length < 1) { this.$message({ message: "短信验证码不能为空!" }); return false; } if (this.password.length < 6 || this.password.length > 16) { this.$message({ message: "对不起,密码长度必须在6-16个字符之间!" }); return false; } this.$axios({ url: this.$settings.Host + 'user/register/mobile/', method: 'post', data: { mobile: this.mobile, password: this.password, sms: this.sms } }).then(response => { let _this = this; let status = response.data.status; let msg = response.data.msg; _this.$message({ message: msg, onClose() { if (status == 0) { // 保存登录状态 sessionStorage.user_name = response.data.user.username; // sessionStorage.user_mobile = response.data.user.mobile; // 跳转到用户中心 // _this.$router.push('/user'); } } }); }).catch(error => { this.$message({ message: error.response.data.result }); }) } }, }; </script> <style scoped> .box { width: 100%; height: 100%; position: relative; overflow: hidden; } .box img { width: 100%; min-height: 100%; } .box .register { position: absolute; width: 500px; height: 400px; left: 0; margin: auto; right: 0; bottom: 0; top: -238px; } .register .register-title { width: 100%; font-size: 24px; text-align: center; padding-top: 30px; padding-bottom: 30px; color: #4a4a4a; letter-spacing: .39px; } .register-title img { width: 190px; height: auto; } .register-title p { font-size: 18px; color: #fff; letter-spacing: .29px; padding-top: 10px; padding-bottom: 50px; } .register_box { width: 400px; height: auto; background: #fff; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5); border-radius: 4px; margin: 0 auto; padding-bottom: 40px; } .register_box .title { font-size: 20px; color: #9b9b9b; letter-spacing: .32px; border-bottom: 1px solid #e6e6e6; display: flex; justify-content: space-around; padding: 50px 60px 0 60px; margin-bottom: 20px; cursor: pointer; } .register_box .title span:nth-of-type(1) { color: #4a4a4a; border-bottom: 2px solid #84cc39; } .inp { width: 350px; margin: 0 auto; } .inp input { outline: 0; width: 100%; height: 45px; border-radius: 4px; border: 1px solid #d9d9d9; text-indent: 20px; font-size: 14px; background: #fff !important; } .inp input.user { margin-bottom: 16px; } .inp .rember { display: flex; justify-content: space-between; align-items: center; position: relative; margin-top: 10px; } .inp .rember p:first-of-type { font-size: 12px; color: #4a4a4a; letter-spacing: .19px; margin-left: 22px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; /*position: relative;*/ } .inp .rember p:nth-of-type(2) { font-size: 14px; color: #9b9b9b; letter-spacing: .19px; cursor: pointer; } .inp .rember input { outline: 0; width: 30px; height: 45px; border-radius: 4px; border: 1px solid #d9d9d9; text-indent: 20px; font-size: 14px; background: #fff !important; } .inp .rember p span { display: inline-block; font-size: 12px; width: 100px; /*position: absolute;*/ /*left: 20px;*/ } #geetest { margin-top: 20px; } .register_btn { width: 100%; height: 45px; background: #84cc39; border-radius: 5px; font-size: 16px; color: #fff; letter-spacing: .26px; margin-top: 30px; } .inp .go_login { text-align: center; font-size: 14px; color: #9b9b9b; letter-spacing: .26px; padding-top: 20px; } .inp .go_login a { color: #84cc39; cursor: pointer; } .sms { position: relative; } .sms .sms_btn { position: absolute; top: -12px; right: 0; bottom: 0; margin: auto; width: 130px; text-align: center; height: 24px; color: #ff7000; cursor: pointer; border-left: 1px solid #999; } </style>
安装依赖
>: pip3 install redis
直接使用
import redis r = redis.Redis(host='127.0.0.1', port=6379)
连接池的使用
import redis pool = redis.ConnectionPool(host='127.0.0.1', port=6379) r = redis.Redis(connection_pool=pool) 支持高并发
缓存使用:要额外的安装django_redis模块
在settings.py中进行配置使用
# 1.将缓存存储位置配置到redis中:settings.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} # 开设池 } } }
# 2.操作cache模块直接操作缓存:views.py from django.core.cache import cache # 结合配置文件实现插拔式 # 存放token,可以直接设置过期时间 cache.set('token', 'header.payload.signature', 10) # 取出token token = cache.get('token')
手机验证接口,
基于之前的二次封装短信验证,导入使用
from rest_framework.views import APIView from .models import User from utils.response import APIResponse import re # 注册逻辑:1.校验手机号是否存在 2.发送验证码 3.完成注册 class MobileAPIView(APIView): def post(self, request, *args, **kwargs): mobile = request.data.get('mobile') if not mobile or not re.match(r'^1[3-9]\d{9}$', mobile): return APIResponse(1, '数据有误') try: User.objects.get(mobile=mobile) return APIResponse(2, '已注册') except: return APIResponse(0, '未注册')
发送短信接口
# 发送验证码接口分析 from libs import txsms from django.core.cache import cache class SMSAPIView(APIView): def post(self, request, *args, **kwargs): # 1)拿到前台的手机号 mobile = request.data.get('mobile') if not mobile or not re.match(r'^1[3-9]\d{9}$', mobile): return APIResponse(2, '数据有误') # 2)调用txsms生成手机验证码 code = txsms.get_code() # 3)调用txsms发送手机验证码 result = txsms.send_sms(mobile, code, 5) # 4)失败反馈信息给前台 if not result: return APIResponse(1, '短信发送失败') # 5)成功服务器缓存手机验证码 - 用缓存存储(方便管理) - redis cache.set('sms_%s' % mobile, code, 5 * 60) # 6)反馈成功信息给前台 return APIResponse(0, '短信发送成功')
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/11768065.html