登录页面修订

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>

login.vue

注册页面修订

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>

Register.vue

python使用redis

安装依赖

>: 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, '短信发送成功')

注册登录页面修订-Python使用redis-手机验证接口-发送短信验证的更多相关文章

  1. Siemens3508手机AT指令发送短信的实验

    凡夫 最近利用Siemens3508旧手机做了AT指令发送短信的实验.有人可能认为我费那么大劲折腾累不累,告诉你这可是废物再利用,可以利用旧手机里的GSM/GPRS模块做无线远程多点分布数据采集.监控 ...

  2. java servlet手机app访问接口(二)短信验证

    今天找了几个短信平台,其实最想使用的一个是sharesdk,使用它上面http api短信功能,不仅价格低,而且最少可以充值100RMB,但是审核过于严格,对应APP还必须集成他们的短信功能,而且要上 ...

  3. 用Python调用华为云API接口发短信

    [摘要] 用Python调用华为云API接口实现发短信,当然能给调用发短信接口前提条件是通过企业实名认证,而且有一个通过审核的短信签名,话不多说,showcode #!/usr/bin/python3 ...

  4. Android手机上监听短信的两种方式

    Android手机上监听短信有两种方式: 1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: ...

  5. 原生js验证简洁美观注册登录页面

    序 一个以js验证表单的简洁的注册登录页面,不多说直接上图 效果 主要文件 完整代码 sign_up.html 注册表单 <!DOCTYPE html> <html lang=&qu ...

  6. PHP实现一个简陋的注册登录页面

    PHP实现一个简陋的注册登录页面 今天来水一篇没有**用的 /滑稽脸,代码简陋臃肿考虑不全,各位大佬轻喷,还望不吝赐教. 首先考虑了一下需要至少四个页面:register.html.register. ...

  7. Luffy之注册认证(容联云通讯短信验证)

    用户的注册认证 前端显示注册页面并调整首页头部和登陆页面的注册按钮的链接. 注册页面Register,主要是通过登录页面进行改成而成. 先构造前端页面 <template> <div ...

  8. C# Ajax 手机发送短信验证码 校验验证码 菜鸟级别实现方法

    1.Ajax请求处理页面: using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...

  9. 使用 Python 发送短信?

    上回食行生鲜签到,我们说到怎么把签到结果发出来,于是就找到了 Twilio. Twilio 是一个位于加利福尼亚的云通信(PaaS)公司,致力于为开发者提供通讯模块的 API.由于 Twilio 为试 ...

随机推荐

  1. Spark 调优

    资源调优 (1). 在部署 spark 集群中指定资源分配的默认参数 在 spark 安装包的 conf 下的 spark-env.sh SPARK_WORKER_CORES SPARK_WORKER ...

  2. javascript中的私有作用域

    我们知道js中所有的块级作用域都是无效的,块级作用域内的变量,在外部仍然可以被读取,其实是申明在外部的.如何实现变量的私有化,只在块级作用域起效,避免污染全局的变量呢.而且,挂载在全局的变量很难被回收 ...

  3. java的形参与实参的区别以及java的方法

    package com.lv.study; public class Demo05 { public static void main(String[] args) { //我想要用什么分隔符进行分隔 ...

  4. CCCC L3-015. 球队“食物链”(dfs+剪枝)

    题意: 某国的足球联赛中有N支参赛球队,编号从1至N.联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场. 联赛战罢,结果已经尘埃落定.此时,联赛主席突发奇想,希望从中找出一条包含所有球队的 ...

  5. 2016蓝桥杯省赛C/C++A组第七题 剪邮票(暴力+并查集)

    题意:有12张连在一起的12生肖的邮票.现在你要从中剪下5张来,要求必须是连着的.(仅仅连接一个角不算相连) 分析:暴力+并查集. 1.记录下每个数字所在位置. 2.先枚举各不相同的5个数的所有可能情 ...

  6. UVA - 11346 Probability(概率)(连续概率)

    题意:在[-a, a]*[-b, b]区域内随机取一个点P,求以(0, 0)和P为对角线的长方形面积大于S的概率(a,b>0, S>=0). 分析: 1.若长方形面积>S,则选取的P ...

  7. 线程与进程 queue模块

    queue模块的基本用法 https://www.cnblogs.com/chengd/articles/7778506.html 模块实现了3种类型的队列,区别在于队列中条目检索的顺序不同.在FIF ...

  8. BZOJ:2190: [SDOI2008]仪仗队

    题解:欧拉函数 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ...

  9. java课程之团队开发冲刺阶段2.8

    昨日总结: 1.具体情况已经写在了昨天的当日总结当中 遇到的问题: 1.toolbar的返回键与菜单键冲突,导致无法同时使用 今天的任务: 1.完整实现课程查询任务 当日总结: 1.完整实现,唯一的遗 ...

  10. UVALive 3977 BFS染色

    这个题意搞了半天才搞明白 就是如果定义一个d-summit,即从该点到另一个更高的点,经过的路径必定是比当前点低至少d高度的,如果该点是最高点,没有比他更高的,就直接视为顶点 其实就是个BFS染色,先 ...