这篇文章主要介绍一下手机号注册,发送短信验证码的功能
觉得有帮助的点赞支持一下吧。
这里我们采用的是阿里大于的服务来实
界面描述还是比较详细的,展示了短信服务的完整流程快速学习短信发送
我们申请完Access Key ID,Access Key Secret,短信签名和短信模板就可以入门编写代码了,同时阿里云也提供了相应的接口调用机制和Demo供我们参考,基本条件完成以后接下来就实现注册功能。
首先是验证码发送服务。我们建立springboot项目采用maven导入相关依赖,pom如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
resources下建立application.yml文件内容如下:
server:
port: #端口号
spring:
application:
name: #新建模块名称
redis:
host: #主机地址
leyou:
sms:
accessKeyId: # 你自己的accessKeyId
accessKeySecret: # 你自己的AccessKeySecret
signName: # 签名名称
verifyCodeTemplate: # 模板名称
配置文件完成以后,我们需要建立实体类,监听短信以及发送短信工具类,代码如下:
实体类SmsProperties
@ConfigurationProperties(prefix = "leyou.sms")
public class SmsProperties {
String accessKeyId;
String accessKeySecret;
String signName;
String verifyCodeTemplate;
//此处省略set和get方法了,实操自行补上
发送短信工具类SmsUtils
@Component
@EnableConfigurationProperties(SmsProperties.class)
public class SmsUtils {
@Autowired
private SmsProperties prop;
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
static final Logger logger = LoggerFactory.getLogger(SmsUtils.class);
public SendSmsResponse sendSms(String phone, String code, String signName, String template) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",
prop.getAccessKeyId(), prop.getAccessKeySecret());
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
request.setMethod(MethodType.POST);
//必填:待发送手机号
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName(signName);
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(template);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
request.setTemplateParam("{\"code\":\"" + code + "\"}");
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("123456");
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
logger.info("发送短信状态:{}", sendSmsResponse.getCode());
logger.info("发送短信消息:{}", sendSmsResponse.getMessage());
return sendSmsResponse;
}
}
此处代码和阿里云短信服务提供的demo基本一致。
监听类SmsListener
@Component
@EnableConfigurationProperties(SmsProperties.class)
public class SmsListener {
@Autowired
private SmsUtils smsUtils;
@Autowired
private SmsProperties smsProperties;
public void sendSms(Map<String,String> msg) throws ClientException {
if (CollectionUtils.isEmpty(msg)){
return;
}
String phone = msg.get("phone");
String code = msg.get("code");
if (StringUtils.isNoneBlank(phone) && StringUtils.isNoneBlank(code)){
this.smsUtils.sendSms(phone,code,this.smsProperties.getSignName(),this.smsProperties.getVerifyCodeTemplate());
}
}
此处接收验证码并发送
至此短信服务模块就构建好了,接下来我们实现验证码的产生及手机号注册。同样我们建立一个新模块作为注册功能。这里我们采用通用mapper实现增删改查,同时利用redis的过期机制来保存验证码,代码如下:
实体类User:
@Table(name = "tb_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Length(min = 4, max = 30, message = "用户名只能在4~30位之间")
private String username;// 用户名
@JsonIgnore //对象序列化为json字符串时忽略该属性
@Length(min = 4, max = 30, message = "密码只能在4~30位之间")
private String password;// 密码
@Pattern(regexp = "^1[35678]\\d{9}$", message = "手机号格式不正确")
private String phone;// 电话
private Date created;// 创建时间
@JsonIgnore
private String salt;// 密码的盐值
此处省略set和get方法
Controller层:
//发送验证码
@PostMapping("code")
public ResponseEntity<Void> sendVerifyCode(@RequestParam("phone")String phone){
this.userService.sendVerifyCode(phone);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
//注册
@PostMapping("register")
public ResponseEntity<Void> register(@Valid User user, @RequestParam("code")String code){
this.userService.register(user,code);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
Service层:
public void sendVerifyCode(String phone) {
//采用工具类生成验证码
String code = NumberUtils.generateCode(6);
if(StringUtils.isBlank(phone)){
return;
}
//保存验证码到redis中
this.redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
}
public void register(User user, String code) {
//查询redis中验证码
String redisCode = this.redisTemplate.opsForValue().get(user.getPhone());
//1.校验验证码
if(!code.equals(redisCode)){
return;
}
//2.生成盐
String salt = CodecUtils.generateSalt();
//3.加盐加密
user.setSalt(salt);
String password = CodecUtils.md5Hex(user.getPassword(),salt);
user.setPassword(password);
//4.新增用户(设置用户id和时间)
user.setId(null);
user.setCreated(new Date());
this.userMapper.insertSelective(user);
}
通用mapper接口
public interface UserMapper extends Mapper<User> {
}
整个发送验证码注册流程大致如此了。