使用邮箱发送验证码前端完成登录

前言

在前一篇使用C#发送邮箱验证码已经完成使用.net core web api写了完成往登录邮箱发送验证码的接口。现在就用前端调用接口模拟登录功能。

接口

 public class ApiResp{public bool Success { get; set; }public int Code { get; set; }public int  count { get; set; }public string msg { get; set; }public object Data { get; set; }}
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Model;
using System.IO;namespace TestSystem.Controllers
{[Route("api/[controller]/[action]")][ApiController]public class UserController : ControllerBase{[HttpPost]public ApiResp email(string username,string email){var resp = new ApiResp();if (username == "admin")//模拟数据库读取 UserName是唯一属性{EmaliSend e = new EmaliSend();string str = e.emailsendone(email);resp.Data = str;resp.Success = true;return resp;}resp.Success = false;return resp;}}
}

前端

前端使用是layui样式+Vue写的功能。
在这里插入图片描述

引入Vue

记得把<div id = "app"></div>把前端样式包含

	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<div class="layui-form-item" v-if="vercodeVisible"><div class="layui-form-item"><label class="layadmin-user-login-icon layui-icon layui-icon-email"for="LAY-user-login-email"></label><input type="text" name="email" v-model="email" placeholder="请输入邮箱" autocomplete="off"class="layui-input"></div><div class="layui-row"><div class="layui-col-xs7"><label class="layadmin-user-login-icon layui-icon layui-icon-vercode"for="LAY-user-login-vercode"></label><input type="text" name="vercode" id="LAY-user-login-vercode" lay-verify="required"v-model="emalistr" placeholder="验证码" class="layui-input"></div><div class="layui-col-xs5"><div style="margin-left: 10px;"><button type="button" class="layui-btn layui-btn-primary layui-btn-fluid"@click="EmailSend" id="emailButton">获取验证码</button></div></div></div></div>	<div class="layui-form-item"><button class="layui-btn layui-btn-fluid" v-if="vercodeVisible" lay-submitlay-filter="LAY-user-login-submit" @click="loginEmail">验证码登录</button>		</div>

Vue写调用发送邮箱api

<script>// 提前引入layui并初始化layer模块layui.use('layer', function() {var layer = layui.layer;new Vue({el: '#app',data: {username: 'admin',email: 'xx@163.com', //邮箱emalistr: '', //邮箱验证码remalistr: '', //缓存邮箱验证码},mounted() {},methods: {EmailSend() {const button = document.getElementById('emailButton'); // 获取按钮元素const originalText = button.innerText; // 原始按钮文本const username = this.username;const email = this.email;// 邮箱格式验证正则表达式const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;if (!emailRegex.test(email)) {layer.msg('请输入正确的邮箱地址', {time: 1000,icon: 5,shade: [0.5, '#000'],shadeClose: true});return; // 邮箱格式不正确,停止执行发送邮件操作}const headers = new Headers();headers.append('Content-Type', 'application/json');const body = JSON.stringify({username,email});button.disabled = true; // 禁用按钮let countDown = 60; // 倒计时时间const timer = setInterval(() => {if (countDown >= 1) {button.innerText = `${countDown}秒后可重发`; // 更新按钮文本countDown--;} else {clearInterval(timer);button.innerText = originalText; // 还原按钮文本button.disabled = false; // 启用按钮}}, 1000);fetch('https://localhost:44301/api/Login/EmaliSendLogin', {method: 'POST',headers: headers,body: body}).then(response => response.json()).then(data => {if (data.success) {layer.msg('发送成功', {time: 500,icon: 6,shade: [0.5, '#000'],shadeClose: true,end: function() {console.log("验证码" + data.data);localStorage.setItem('remalistr', data.data);}});} else {layer.msg('发送失败', {time: 1000,icon: 5,shade: [0.5, '#000'],shadeClose: true});}}).catch(error => {console.log(error);layer.msg('发送失败,请检查网络连接', {time: 1000,icon: 5,shade: [0.5, '#000'],shadeClose: true});});},loginEmail() {const username = this.username;const email = this.email;const emalistr = this.emalistr;const remalistr = localStorage.getItem('remalistr');const vercode = this.vercode;const operator = this.operator;const headers = new Headers();headers.append('Content-Type', 'application/json');const body = JSON.stringify({username,email,});fetch('https://localhost:44301/api/Login/LoginEmail', {method: 'POST',headers: headers,body: body}).then(response => response.json()).then(data => {if (data.success && localStorage.getItem('remalistr') === this.emalistr && this.vercode == this.rvercode) {layer.msg('登录成功', {time: 1000,icon: 6,shade: [0.5, '#000'],shadeClose: true,end: function() {console.log(data.data);localStorage.setItem('data', JSON.stringify(data.data));location.href = '../';}});} else {layer.msg('登录失败', {time: 1000,icon: 5,shade: [0.5, '#000'],shadeClose: true});}}).catch(error => {console.log(error);});},}});});</script>

结果

在这里插入图片描述
右侧那验证码是缓存中的验证码,一般是看不见的。

主要逻辑

前端调用后端发送验证码的方法,传入username和邮箱。username是唯一,在数据库不可重复。
后端返回JSON格式给前端,前端解析返回的验证码以及其他用户信息可以进行验证码的读取,然后用户收到邮箱发来的验证码可以进行登录,进行用户输入的验证码和浏览器缓存的验证码进行比对然后登录成功。
还可以添加进行验证码的过期策略以及添加多种验证登录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327916.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

案例介绍|钡铼助力2023年全国职业院校技能大赛工业网络智能控制与维护赛项

如今&#xff0c;越来越多的企业开始意识到数字制造和工业物联网已经成为工业自动化中大规模生产的核心驱动力。这其中&#xff0c;工业网络作为基础设施&#xff0c;是实现工厂设备联网与数据采集&#xff0c;建设数字工厂的基础和前提&#xff0c;甚至成为关乎数字工厂能否真…

【AIGC工具】我找到了使用大模型问答的最短路径!

大家好&#xff0c;我是豆小匠~ 好久没介绍提高效率的工具啦&#xff0c;这次来介绍一个UTools的骚操作&#xff0c;可以极速打开LLM进行提问&#xff01; 完成后的效果是&#xff1a; 快捷键调出输入框&#xff1b;2. 输入问题&#xff1b;3. 选择模型&#xff1b;4. 回车提…

Embedded-Project项目介绍

Embedded-Project项目介绍 Server后端项目后端启动连接数据库启动时可能遇到的问题架构介绍 web前端项目前端启动启动时可能遇到的问题架构介绍 前后端分离开发流程 项目地址&#xff1a; https://github.com/Catxiaobai/Embedded-Project Server后端项目 系统后端项目&#…

C++ 类的内存分布

文章目录 1 . 前言2 . 无继承&#xff0c;无虚函数3 . 无继承&#xff0c;有虚函数4 . 单一继承&#xff0c;无虚函数5 . 单一继承&#xff0c;有虚函数&#xff0c;虚析构6 . 多重继承7 . 菱形继承8 . 虚拟继承9 . 总结 【极客技术传送门】 : https://blog.csdn.net/Engineer_…

【机器学习】循环神经网络(二)-LSTM示例(keras)国际航空乘客问题的回归问题...

使用 Keras 在 Python 中使用 LSTM 循环神经网络进行时间序列预测 国际航空乘客问题的回归问题 这个文件是一个CSV格式的数据集&#xff0c;它包含了从1949年1月到1960年12月的每个月的国际航空乘客的总数&#xff08;以千为单位&#xff09;。第一行是列名&#xff0c;分别是&…

案例099:基于微信小程序的外卖小程序的研究与开发

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

期货日数据维护与使用_日数据维护_日数据更新

目录 写在前面&#xff1a; 下载日数据 下载“新增合约”日数据 下载“待更新合约”日数据 日数据文件 “选择日数据所在目录”按钮点击 “执行”按钮点击 sqlite3代码 按钮点击后执行的代码 子线程代码 写在前面&#xff1a; 本文默认已经创建了项目&#xff0c;如…

pytorch集智-2单车预测器

完整代码在个人主页简介链接pytorch路径下可找到 1 单车预测器1.0 1.1 人工神经元 对于sigmoid函数来说&#xff0c;w控制函数曲线的方向&#xff0c;b控制曲线水平方向位移&#xff0c;w控制曲线在y方向的幅度 1.2 多个人工神经元 模型如下 数学上可证&#xff0c;有限神经…

篇三:让OAuth2 server支持密码模式

由于Spring-Security-Oauth2停止维护&#xff0c;官方推荐采用 spring-security-oauth2-authorization-server&#xff0c;而后者默认不支持密码授权模式&#xff0c;本篇实战中采用的版本如下&#xff1a; <dependency><groupId>org.springframework.security<…

jsES6+新语法

目录 模板字符串标签模板字符串 函数增强默认值与解构剩余参数rest和arguments 箭头函数 展开语法SymbolSetSet方法weakSetweakSet常用方法 MapMap常用方法weakMapweakMap常用方法 PromiseProxy/Reflect迭代器与生成器ES6新增方法includes**Object.valuesObject.entriespadStar…

裁员+失恋或许不能比这更遭了,敬一塌糊涂与充满感动的2023,也敬曾经的挚爱与寒冬的冰霜

~ 随机抽取评论区的 3位 小伙伴送上精美礼品 ~ 参与方式&#xff1a;关注、点赞、收藏&#xff0c;评论 "2024&#xff0c;一天当做两天卷&#xff01;" 活动时间&#xff1a;截止到 2024-01-21 00:00:00 礼品清单&#xff1a;CSDN活动周边、自选图书 本文目录 序 …

基于SSM的毕业设计选题系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…