Java开发-企业-短信验证码登录
·
1.具体的实现步骤:
接口1:发送短信验证码
在一开始进行判断是否上锁:如果上锁则直接退出,提示不要频繁发送消息?没有上锁就是第一次,就正常发送消息
1.UUID生成6位数验证码
2.将验证码存入到redis中
3.进行发送消息(消息成功发送的分支上)
4.对消息上锁60秒
接口2:点击登录验证(这个说的有点粗糙)
取出redis中存的key保存起来,删除redis数据库中的key
1.redis中的验证码是否等于前端用户输入的
2.redis中的验证码是否失效
3.将手机号和数据库中的手机号进行比对,看看是否存在
2.具体的业务代码:
2.1 Controller层:
package net.lab1024.sa.admin.module.mqtt.captcha;
import io.lettuce.core.dynamic.annotation.Value;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = "短信验证登录测试")
public class CaptchaDemoController {
@Resource
private CaptchDemoService captchDemoService;
/**
* 获取手机短信验证码
* @return
*/
@GetMapping("/captchaDemo/")
public ResponseDTO<String> captchaDemo(String phoneNumber) {
return captchDemoService.captchaDemo(phoneNumber);
}
/**
* 验证手机短信验证码
*/
@GetMapping("/captchaDemo/check")
public ResponseDTO checkCaptcha(String phone , String captcha) {
return captchDemoService.checkCaptcha(phone , captcha);
}
}
2.2 Service层
package net.lab1024.sa.admin.module.mqtt.captcha;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.teaopenapi.models.Config;
@Service
public class CaptchDemoService {
private final String accessKeyId = "**********";
private final String accessKeySecret = "***************";
private final String signName = "************";
private final String templateCode = "****************";
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private EmployeeDao employeeDao;
/**
* 发送验证码
*
* @return
*/
public ResponseDTO<String> captchaDemo(String phoneNumber) {
//在一开始进来的时候进行判断
if (redisTemplate.hasKey("captcha:" + phoneNumber)) {
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "请勿频繁发送验证码");
}
//1. 生成6位数验证码
String code = generateCode(6);
//2.将验证码保存到redis中,1分钟有效期
redisTemplate.opsForValue().set("captcha:" + phoneNumber, code, 1, java.util.concurrent.TimeUnit.MINUTES);
//3.发送验证码
try {
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
config.endpoint = "dysmsapi.aliyuncs.com";
Client client = new Client(config);
// 确保手机号带国家代码
String formattedPhone = phoneNumber.startsWith("+") ? phoneNumber : "+86" + phoneNumber;
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(formattedPhone);
request.setSignName(signName);
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"code\":\"" + code + "\"}");
client.sendSms(request);
//发送信息后进行上锁
String lockKey = "captcha_lock:" + phoneNumber;
redisTemplate.opsForValue().set(lockKey, "locked", 60, TimeUnit.SECONDS);
return ResponseDTO.ok("发送成功");
} catch (Exception e) {
e.printStackTrace();
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "发送失败");
}
}
/**
* 校验验证码
*
* @param phone
* @param captcha
* @return
*/
public ResponseDTO checkCaptcha(String phone, String captcha) {
//1.从redis中获取验证码
String redisCaptcha = (String) redisTemplate.opsForValue().get("captcha:" + phone);
// 验证成功后删除该验证码
redisTemplate.delete("captcha:" + phone);
//2.开始比对验证码
if (!redisCaptcha.equals(captcha)) {
//返回验证码错误
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "验证码不正确");
}
if (redisCaptcha == null) {
//返回验证码已过期
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "验证码已过期");
}
//3.数据库查询手机号,判断用户是否存在,存在就返回用户信息(并不执行注册功能)
List<EmployeeEntity> employeeEntities = employeeDao.queryByPhone(phone);
if (employeeEntities.size() > 0) {
return ResponseDTO.ok(employeeEntities.get(0));
} else {
return ResponseDTO.error(UserErrorCode.USER_NOT_EXIST, "用户不存在!!!");
}
}
// 生成指定位数的数字验证码
private String generateCode(int length) {
java.util.Random random = new java.util.Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(random.nextInt(10));
}
return sb.toString();
}
}
2.3 然后是pom.xml文件里面引入阿里云短信开发的依赖
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.1.6</version>
</dependency>
2.4 最后就是阿里云四个配置属性:service层里面打*的
private final String accessKeyId = "**********";
private final String accessKeySecret = "***************";
private final String signName = "************";
private final String templateCode = "****************";
1.最后说一下,最难申请的是密钥这些,一般个人是学生的话,几乎申请不到,如果是个人开发者,需要提交资质啊什么的,但是在公司里会给你这四个数据
2.我开发的其实是比较不严谨的,没有把配置类写在yml文件内,也没有把发送信息的这个过程打包成工具包
3.但是你拿到我代码可以直接用
更多推荐



所有评论(0)