IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 汽车售票系统——短信验证码实现注册,Redis存储 -> 正文阅读

[JavaScript知识库]汽车售票系统——短信验证码实现注册,Redis存储

首先需要导入腾讯云短信验证、Redis的依赖,开启腾讯云短信服务。

我们要实现的用户注册界面大致如下:
在这里插入图片描述
本项目中主要使用ajax进行数据交互

注册的html代码:

<form class="m-t" role="form" action="login.html">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="请输入用户名" id="usernameSignup" required="">
                </div>
                <div class="form-group">
                    <input type="password" class="form-control" placeholder="请输入密码" id="passwordSignup" required="">
                </div>
                <div class="form-group">
                    <input type="password" class="form-control" placeholder="请再次输入密码" id="repasswordSignup" required="">
                </div>
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="请输入手机号" id="phoneSignup" required="">
                    <a href="javascript:void(0); onclick(toSave())">发送验证码</a>
                </div>
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="请输入验证码" id="params" required="">
                </div>
                <div class="form-group text-left">
                    <div class="checkbox i-checks">
                        <label class="no-padding">
                            <input type="checkbox"><i></i> 我同意注册协议</label>
                    </div>
                </div>
<!--                <button  onClick="signupSubmit()" class="btn btn-primary block full-width m-b">注 册</button>-->
                <a href="javascript:void(0); onclick(signupSubmit())" class="btn btn-primary block full-width m-b">注 册</a>

                <p class="text-muted text-center"><small>已经有账户了?</small><a href="login.html">点此登录</a>
                </p>

            </form>

我们这里只说输入手机号后,点击发送验证码之后的过程。
先看html,输入手机号后,这个值就在id=“phoneSignup"中,js通过var phoneSignup = $(”#phoneSignup").val()来获取。

下面是js中发送验证码的函数toSave():
先判断手机号的格式等问题,没有问题后通过"…/saveTX",将有手机号信息的json转化为字符串发送给后端,让后端去处理逻辑。

function toSave(){
	var phoneSignup = $("#phoneSignup").val();
	var json = {"phoneSignup":phoneSignup}
	var msg = ""
	if(phoneSignup.length === 0){
		alert(msg + "你输入的手机号为空,请重新输入")
		return;
	}
	//ajax传递数据
	$.ajax({
		type:'POST',
		url: "../saveTX",
		data:JSON.stringify(json),
		contentType:'application/json;charset=utf-8',
		dataType:'json',
		success: function(data){
			alert("短信发送成功,请在1分钟之内填写")
			localStorage.setItem("params",data.data.params());
		}
	})
}

我们主要看后端对短信验证码的逻辑处理。
首先是controller层

// 短信验证码发送
    @PostMapping("/saveTX")
    @GetMapping("/saveTX")
    @ResponseBody
    public Result saveTX(@RequestBody JSONObject jsonObject){
        Result result = new Result();
        String phone = jsonObject.getString("phoneSignup");
        String t = "1349358";	//腾讯云中发送短信的格式id
        //生成随机的六位数
        int ttt = (int) ((Math.random()*9+1)*100000);
        String params = String.valueOf(ttt);
        try {
            tengXunSMSUtils.sendShortMessage(t,phone,params);
            redisService.set(tokenId+phone,params);
            redisService.expire(tokenId+phone,620);//调用reids工具类中存储方法设置超时时间

            result.setStateCode(200);
            result.setMsg("登录成功");
            result.setData(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

TengXunSMSUtils是腾讯云短信发送的工具类,实现了对短信的发送。

@Component
public class TengXunSMSUtils {
    public static final String VALIDATE_CODE = "866988";

    public  boolean sendShortMessage(String templateCode, String phoneNum, String param) throws Exception {
        try {
            /*
             * CAM 密钥查询:https://console.cloud.tencent.com/cam/capi
             */
            Credential cred = new Credential("**********", "***************");
            // 无特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();

            httpProfile.setReqMethod("POST");

            httpProfile.setConnTimeout(60);

            httpProfile.setEndpoint("sms.tencentcloudapi.com");

            ClientProfile clientProfile = new ClientProfile();

            clientProfile.setSignMethod("HmacSHA256");
            clientProfile.setHttpProfile(httpProfile);
            /* 实例化 SMS 的 client 对象
             * 第二个参数是地域信息,可以直接填写字符串 ap-guangzhou,或者引用预设的常量 */
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            /* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
             * 您可以直接查询 SDK 源码确定接口有哪些属性可以设置
             * 属性可能是基本类型,也可能引用了另一个数据结构
             * 推荐使用 IDE 进行开发,可以方便地跳转查阅各个接口和数据结构的文档说明 */
            com.tencentcloudapi.sms.v20190711.models.SendSmsRequest req = new SendSmsRequest();
            /* 填充请求参数,这里 request 对象的成员变量即对应接口的入参
             * 您可以通过官网接口文档或跳转到 request 对象的定义处查看请求参数的定义
             * 基本类型的设置:
             * 帮助链接:
             * 短信控制台:https://console.cloud.tencent.com/smsv2
             * sms helper:https://cloud.tencent.com/document/product/382/3773 */
            /* 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SDKAppID,例如1400006666 */
            String SdkAppid = "*********";
            req.setSmsSdkAppid(SdkAppid);
            /* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,可登录 [短信控制台] 查看签名信息 */
            String sign = "snicker个人网站";
            req.setSign(sign);
            /* 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper] */
            String senderid = "";
            req.setSenderId(senderid);
            /* 模板 ID: 必须填写已审核通过的模板 ID,可登录 [短信控制台] 查看模板 ID */
            req.setTemplateID(templateCode);
            /* 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号]
             * 例如+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号*/
            String[] phoneNumber = {"+86" + phoneNum + ""};
            req.setPhoneNumberSet(phoneNumber);
            /* 模板参数: 若无模板参数,则设置为空*/
            String[] templateParams = {param,"1"};
            req.setTemplateParamSet(templateParams);
            /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例,与请求对象对应 */
            SendSmsResponse res = client.SendSms(req);
            // 输出 JSON 格式的字符串回包
            System.out.println(SendSmsResponse.toJsonString(res));
            // 可以取出单个值,您可以通过官网接口文档或跳转到 response 对象的定义处查看返回字段的定义
            System.out.println(res.getRequestId());
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return true;
    }
}

RedisService

public interface RedisService {

    /**
     * 存储数据
     */
    void set(String key, String value);

    /**
     * 获取数据
     */
    String get(String key);

    /**
     * 设置超期时间
     */
    boolean expire(String key, long expire);

    /**
     * 删除数据
     */
    void remove(String key);

    /**
     * 自增操作
     * @param delta 自增步长
     */
    Long increment(String key, long delta);

}

RedisServiceImpl

@Service
public class RedisServiceImpl implements RedisService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    @Override
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public boolean expire(String key, long expire) {
        return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }

    @Override
    public void remove(String key) {
        stringRedisTemplate.delete(key);
    }

    @Override
    public Long increment(String key, long delta) {
        return stringRedisTemplate.opsForValue().increment(key,delta);
    }

}

在saveTX的controller中,通过redisService.set(tokenId+phone,params) 和 redisService.expire(tokenId+phone,60) 将key为手机号,value为随机数验证码存入Redis中,并设置过期时间为60秒。

之后我们在输入框中输入所有信息后,在通过js中的函数进行处理分析,发送给后端请求,data:JSON.stringify(json)。

function signupSubmit(){
	var username = $("#usernameSignup").val();
	var password = $("#passwordSignup").val();
	var passwordAgain = $("#repasswordSignup").val();
	var phoneSignup = $("#phoneSignup").val();
	var params = $("#params").val();

	//判断
	var msg = ""
	if(username.length === 0){
		alert(msg + "你输入的用户名为空,请重新输入")
		return;
	}
	if(password.length === 0){
        alert(msg + "你输入的密码为空,请重新输入")
		return;
	}
	if(passwordAgain !== password){
		alert(msg + "你输入的密码不一致,请重新输入")
		return;
	}
	if(phoneSignup.length === 0){
		alert(msg + "你输入的手机号为空,请重新输入")
		return;
	}
	if(params.length === 0){
		alert(msg + "你输入的验证码为空,请重新输入")
		return;
	}
	if(params.length !== 6){
		alert(msg + "你输入的验证码格式,请重新输入")
		return;
	}
	var json = {"username":username,"password":password,"passwordAgain":passwordAgain,"phoneNum":phoneSignup,"params":params}
	//ajax传递数据
	$.ajax({
	    type:'POST',
	    url: "../regist",
	    data:JSON.stringify(json),
	    contentType:'application/json;charset=utf-8',
	    dataType:'json',
	    success: function(data){
	        if (data.stateCode === 200){
	            //注册成功
				alert("注册成功,请登录")
	        	console.log("signupSubmit函数提交的json信息处理后返回200,准备跳转到登陆页面。");
	        	window.location.href = 'login.html';
	        }
	        else{
	            //注册失败,错误信息在data.msg里面
	        	console.log("signupSubmit函数提交的json信息处理后返回错误,alert输出data.msg中的错误信息。");
	            alert("错误信息:" + data.msg)
	        }
	    }
	})
}

然后后端中对整个注册的信息进行分析,没有问题就存入数据库,注册成功。要是遇到验证码错误或者失效,用户名重复等问题,放回错误信息给用户。
controller层:

@PostMapping("/regist")
    public Result registUser(@RequestBody User userData){
        return loginService.registUser(userData);
    }

service层:
将前端传来的用户输入的验证码等信息与Redis中存放的验证码进行对比,如果验证码错误,放回用户相应的错误信息。如果验证码一致,将数据插入数据库,报错提取异常,插入失败,否则,注册成功。

	@Override
    @Transactional
    public Result registUser(User userData) {
        Result result = new Result();
        String phone = userData.getPhoneNum();
        String params = userData.getParams();
        String redisauthcode = redisService.get(tokenId + phone);
        if (StringUtils.isEmpty(redisauthcode)) {
            //如果未取到则过期验证码已失效
            result.setStateCode(404);
            result.setMsg("验证码失效");
            result.setData(false);
        } else if (!"".equals(redisauthcode) && !params.equals(redisauthcode)) {
            //验证码错误
            result.setStateCode(500);
            result.setMsg("验证码错误");
            result.setData(false);
        } else {
            try{
                userDao.insertUserRegisterInfo(userData);
                result.setStateCode(200);
                result.setMsg("注册成功");
                result.setData(userData.getUsername());
            }catch (Exception e){
                result.setStateCode(400);
                result.setMsg("注册失败,用户名已经存在");
                result.setData(false);
            }
        }
        return result;
    }
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:14:27  更:2022-04-09 18:18:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:42:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码