发送短信验证码

选择短信接入服务商

服务商

  • 阿里云短信
  • 腾讯云短信
  • 百度云SMS
  • 荣联云通讯

接入步骤

  1. 注册开发者账号
  2. 创建应用
  3. 对接测试
  4. 上线运营

1.注册云通讯账号:https://www.yuntongxun.com/

image-20211029162306108

2.设置平台测试号码

image-20211029162500952

image-20211029170922900

SDK

sdk+md5: https://www.lanzouw.com/imDFWvwq8tg

image-20211029172647552

发送短信验证码

1
2
3
4
5
6
<!--云通讯 Java SMS SDK-->
<dependency>
<groupId>com.cloopen</groupId>
<artifactId>java-sms-sdk</artifactId>
<version>1.0.3</version>
</dependency>

service

创建用户,生成验证码(1111-9999),发送验证码,缓存验证码到redis

1
2
3
4
5
6
//创建用户
public void itripCreateUserByPhone(ItripUser user) throws Exception;
//验证手机验证码
public boolean validatePhone(String phonenum,String code);
//根据手机号获取用户信息
public ItripUser findUserByUserCode(String userCode);

serviceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Autowired
public ItripUserService userService;

@Resource
RedisAPI redisAPI;
//手机验证码
@Override
public void itripCreateUserByPhone(ItripUser user) throws Exception {
//1.创建用户
userService.save(user);
//2.生成验证码(1111-9999)
int code = MD5.getRandomCode();
//3.手机发送激活码
/*1.初始化第三方*/
CCPRestSmsSDK sdk = new CCPRestSmsSDK();
//初始化服务地址和端口
sdk.init("app.cloopen.com","8883");
//初始化主账号信息
sdk.setAccount("ACCOUNT SID(主账户ID)","AUTH TOKEN(账户授权令牌)");
//初始化应用ID
sdk.setAppId("AppID(默认)");

/*2.调用方法 手机号 默认模板 转为string类型 时间 */
HashMap result = sdk.sendTemplateSMS(user.getUsercode(),"1",new String[]{String.valueOf(code),"3"});
System.out.println("phone==>"+user.getUsercode());
System.out.println("result==>"+result);
if ("000000".equals(result.get("statusCode"))){
System.out.println("短信发送成功!");
}else {
throw new Exception(result.get("statusCode")+result.get("statusMsg").toString());
}

//4.将激活码存入Redis中
redisAPI.set("action"+user.getUsercode(),String.valueOf(code),180);//设置验证码三分钟有效
System.out.println(redisAPI.get("action"+user.getUsercode()));
//return String.valueOf(code);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//手机短信验证
public boolean validatePhone(String phonenum,String code){
//1.对比验证码
String value = (String) redisAPI.get("action"+phonenum);
System.out.println("验证码=>"+value);
if (null != value && value.equals(code)){
ItripUser user = this.findUserByUserCode(phonenum);
System.out.println("获取用户=>"+user);
if (null != user){
//2.更新用户激活状态
user.setActivated(1);
user.setFlatid(user.getId());
user.setUsertype(0);
userService.updateById(user);
return true;//返回验证成功
}
}
return false;//否则验证失败
}
@Override
public ItripUser findUserByUserCode(String userCode){
Map<String,Object> param = new HashMap<>();
param.put("userCode",userCode);
List<ItripUser> users = userService.listByMap(param);
if (users.size()>0){
return users.get(0);
}else {
return null;
}
}

controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//手机注册
@PostMapping("/registerByPhone")
@ApiOperation(value = "手机注册", notes = "传入ItripUserVO")
public R registerByPhone(@RequestBody ItripUserVO userVO) throws Exception {
//1.手机验证
if (!this.validPhone(userVO.getUserCode()))
return ResponseDataUtils.buildError("请使用正确的手机号");
//调用service添加
ItripUser user = new ItripUser();
user.setUsercode(userVO.getUserCode());
user.setUsername(userVO.getUserName());
try {
if (null != userService.findUserByUserCode(user.getUsercode()))
return ResponseDataUtils.buildError("用户已存在");
else{
user.setUserpassword(SecureUtil.md5(userVO.getUserPassword()));
userService.itripCreateUserByPhone(user);
return ResponseDataUtils.buildSuccess("用户添加成功");
}
}catch (Exception e){
e.printStackTrace();
return ResponseDataUtils.buildError("失败");
}
}
//手机短信验证
@PostMapping("/validatephone")
@ApiOperation(value = "手机短信验证", notes = "传入user,code")
public R validatephone(@RequestParam String user,@RequestParam String code){
try {
if (userService.validatePhone(user, code))
return ResponseDataUtils.buildSuccess("验证成功");
else
return ResponseDataUtils.buildSuccess("验证失败");
}catch (Exception e){
e.printStackTrace();
return ResponseDataUtils.buildError("验证失败");,
}
}

/**
* 验证手机号是否合法
* @param phone
* @return
*/
private boolean validPhone(String phone){
String regex="^1[3578]{1}\\d{9}$";
return Pattern.compile(regex).matcher(phone).find();
}


输入手机号,密码 ,名字测试

1
http://localhost:8081/auth/api/registerByPhone
1
2
3
4
5
{
"userCode": "13663797602",
"userName": "asd",
"userPassword": "123"
}
1
2
3
4
5
6
7
8
9
==>  Preparing: INSERT INTO itrip_user ( usercode, userpassword, username ) VALUES ( ?, ?, ? )
==> Parameters: 13663797602(String), 202cb962ac59075b964b07152d234b70(String), asd(String)
<== Updates: 1

phone==>13663797602
result==>{data={templateSMS={dateCreated=20211029161603, smsMessageSid=c3f097fa6fca4d06a9105f2dd3bfbc8d}}, statusCode=000000}
短信发送成功!
2111

image-20211029170707119

验证码存入redis服务器

image-20211029164842548

验证短信验证码

1
http://localhost:8081/auth/api/validatephone?code=2111&user=13663797602
1
2
3
4
5
6
7
对比验证码=>2111
==> Preparing: SELECT id,usercode,userpassword,usertype,flatid,username,wechat,qq,weibo,baidu,creationdate,createdby,modifydate,modifiedby,activated FROM itrip_user WHERE userCode = ?
==> Parameters: 13663797602(String)
<== Columns: id, usercode, userpassword, usertype, flatid, username, wechat, qq, weibo, baidu, creationdate, createdby, modifydate, modifiedby, activated
<== Row: 77, 13663797602, 202cb962ac59075b964b07152d234b70, null, null, asd, null, null, null, null, null, null, null, null, null
<== Total: 1

验证码正确更新用户激活状态

1
2
3
==>  Preparing: UPDATE itrip_user SET usercode=?, userpassword=?, usertype=?, flatid=?, username=?, activated=? WHERE id=?
==> Parameters: 13663797602(String), 202cb962ac59075b964b07152d234b70(String), 0(Integer), 77(Long), asd(String), 1(Integer), 77(Long)
<== Updates: 1

验证成功

1
2
3
4
5
{
"code": 200,
"message": "验证成功",
"data": null
}

image-20211029165915476

邮箱验证码

引入邮箱依赖

1
2
3
4
5
<!--email依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

配置yml

1
2
3
4
5
6
7
spring:
##Email配置
mail:
host: smtp.qq.com #邮箱服务商的smtp地址
username: # 邮箱
password: # 邮箱服务商授权码
default-encoding: utf-8 #

发送方必须要开启smtp,获取到的授权码,QQ邮箱获取授权码方法:
https://service.mail.qq.com/cgi-bin/help?subtype=1&&no=1001256&&id=28

EmailMessage

邮件发送接口主要使用JavaMailSender

参数说明:
subject :邮件主题
content :邮件主题内容
from:发件人Email地址
to:收件人Email地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.ytzl.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

/**
* 用于邮箱发送
*/
@Service
public class EmailMessage {
@Value("${spring.mail.username}")
private String from;

@Autowired
JavaMailSender javaMailSender;

/**
* 邮件发送
* @param userCode 用户账号
* @param activaCode 激活码
*/
public void placeOrder(String userCode,String activaCode){
//只能用来发送文本格式的邮件
SimpleMailMessage simpleMailMessage=new SimpleMailMessage();
simpleMailMessage.setFrom(from);
simpleMailMessage.setSubject("subject");
simpleMailMessage.setTo(userCode);//用户接收的邮箱
simpleMailMessage.setText("您好!\n" +
"您正在申请发送验证码:\n" +
"为了账号安全,请在指定位置输入下列验证码: "+activaCode+"。 验证码涉及个人账号隐私安全,切勿向他人透漏。:");//发送的内容是激活码
javaMailSender.send(simpleMailMessage);//发送邮件

}
}

service

1
2
3
4
   //发送
public void sendEmail(ItripUser user) throws Exception;
//验证
public boolean validateEmail(String email,String code);

serviceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@Autowired
EmailMessage message;
/*邮箱注册*/
public void sendEmail(ItripUser user){
//1.添加用户
userService.save(user);
//2.生成激活码(根据时间,随机数)
String activationCode = MD5.getMd5(new Date().toLocaleString(),32);
System.out.println("激活码==》"+activationCode);
//3.发送邮箱
message.placeOrder(user.getUsercode(),activationCode);
System.out.println("短信发送成功");
//4.激活码存入Redis(具有过期时间的set)
redisAPI.set("action"+user.getUsercode(),activationCode,30*60);
System.out.println(redisAPI.get("action"+user.getUsercode()));
//return activationCode;
}

//邮箱验证
public boolean validateEmail(String email,String code){
//1.对比验证码
String value = (String) redisAPI.get("action"+email);
System.out.println("验证码=>"+value);
if (null != value && value.equals(code)){
ItripUser user = this.findUserByUserCode(email);
System.out.println("获取用户=>"+user);
if (null != user){
//2.更新用户激活状态
user.setActivated(1);
user.setFlatid(user.getId());
user.setUsertype(0);
userService.updateById(user);
return true;//返回验证成功
}
}
return false;//否则验证失败
}

@Override
public ItripUser findUserByUserCode(String userCode){
Map<String,Object> param = new HashMap<>();
param.put("userCode",userCode);
List<ItripUser> users = userService.listByMap(param);
if (users.size()>0){
return users.get(0);
}else {
return null;
}
}

controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//邮箱注册
@PostMapping("/registerByEmail")
@ApiOperation(value = "邮箱注册", notes = "传入ItripUserVO")
public R registerByEmail(@RequestBody ItripUserVO userVO) throws Exception {
//1.邮箱验证
if (!this.validEmail(userVO.getUserCode()))
return ResponseDataUtils.buildError("请使用正确的邮箱");//"",
//调用service添加
ItripUser user = new ItripUser();
user.setUsercode(userVO.getUserCode());
user.setUsername(userVO.getUserName());
try {
if (null != userService.findUserByUserCode(user.getUsercode()))
return ResponseDataUtils.buildError("邮箱已存在");//,
else{
user.setUserpassword(SecureUtil.md5(userVO.getUserPassword()));
userService.sendEmail(user);
return ResponseDataUtils.buildSuccess(CodeResultEnums.SUCCESS);
}
}catch (Exception e){
e.printStackTrace();
return ResponseDataUtils.buildError(CodeResultEnums.CITY_ERROR);//e.getMessage(),
}
}
//邮箱验证
@PostMapping("/validateEmail")
@ApiOperation(value = "邮箱验证", notes = "传入user,code")
public R validateEmail(@RequestParam String email,@RequestParam String code){
try {
if (userService.validateEmail(email, code))
return ResponseDataUtils.buildSuccess("验证成功");
else
return ResponseDataUtils.buildSuccess("验证失败");
}catch (Exception e){
e.printStackTrace();
return ResponseDataUtils.buildError(CodeResultEnums.CITY_ERROR);//"验证失败",
}
}

/**
* 验证邮箱是否合法
* @param phone
* @return
*/
private boolean validEmail(String email){
String regex = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$";
return Pattern.compile(regex).matcher(email).find();
}

image-20211030143124953

image-20211030143056520