首先需要导入腾讯云短信验证、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>
<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({
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";
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);
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 {
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);
SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
com.tencentcloudapi.sms.v20190711.models.SendSmsRequest req = new SendSmsRequest();
String SdkAppid = "*********";
req.setSmsSdkAppid(SdkAppid);
String sign = "snicker个人网站";
req.setSign(sign);
String senderid = "";
req.setSenderId(senderid);
req.setTemplateID(templateCode);
String[] phoneNumber = {"+86" + phoneNum + ""};
req.setPhoneNumberSet(phoneNumber);
String[] templateParams = {param,"1"};
req.setTemplateParamSet(templateParams);
SendSmsResponse res = client.SendSms(req);
System.out.println(SendSmsResponse.toJsonString(res));
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);
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({
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{
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;
}
|