首先需要导入腾讯云短信验证、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;
}
本文详细介绍了前端用户注册界面的实现,包括手机号验证、发送短信验证码的功能,以及后端如何利用腾讯云短信服务和Redis进行验证码处理。在用户提交注册信息时,前端会检查输入并发送包含所有信息的请求,后端则验证验证码并与Redis中的数据比对,确保注册过程的安全性。

1819

被折叠的 条评论
为什么被折叠?



