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.但是你拿到我代码可以直接用

你可能感兴趣的:(Java初入公司,java,开发语言)