1.首先这里使用的是阿里云的短信服务。
package com.wzy.util;; import cn.hutool.captcha.generator.RandomGenerator; import com.aliyun.dysmsapi20170525.Client; import com.wzy.entity.Ali; import org.springframework.stereotype.Component; /** * @Author: 顾安 * @Description: * @Date: Create in 17:30 2024/7/23 */ @Component public class SendMsgUtil { /** * 使用AK&SK初始化账号Client * @return Client * @throws Exception */ private static Ali ali; public SendMsgUtil(Ali ali) { this.ali = ali; } public static Client createClient() throws Exception { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。 .setAccessKeyId(ali.getAccessKeyId()) // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。 .setAccessKeySecret(ali.getAccessKeySecret()); // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi config.endpoint = "dysmsapi.aliyuncs.com"; return new Client(config); } /* * * API 相关 * @return OpenApi.Params*/ public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception { com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params() // 接口名称 .setAction("SendSms") // 接口版本 .setVersion("2017-05-25") // 接口协议 .setProtocol("HTTPS") // 接口 HTTP 方法 .setMethod("POST") .setAuthType("AK") .setStyle("RPC") // 接口 PATH .setPathname("/") // 接口请求体内容格式 .setReqBodyType("json") // 接口响应体内容格式 .setBodyType("json"); return params; } public static String sendCode(String phone) throws Exception { com.aliyun.teaopenapi.Client client = createClient(); com.aliyun.teaopenapi.models.Params params = createApiInfo(); String code="123456"; // query params java.util.Map<String, Object> queries = new java.util.HashMap<>(); queries.put("PhoneNumbers", phone); queries.put("SignName", ali.getSignName()); queries.put("TemplateCode", ali.getTemplateCode()); //您正在申请手机注册,验证码为:${code},5分钟内有效! queries.put("TemplateParam", "{\"code\":\""+codes()+"\"}"); // runtime options com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions(); com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest() .setQuery(com.aliyun.openapiutil.Client.query(queries)); // 复制代码运行请自行打印 API 的返回值 // 返回值为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode。 client.callApi(params, request, runtime); return codes(); } public static String codes(){ // 自定义纯数字的验证码(随机4位数字,可重复) RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); return String.valueOf(randomGenerator); } // public static String code(){ // return String.valueOf(ThreadLocalRandom.current().nextInt(100000,1000000)); // } }
上面的一些属性没有直接写到代码中,而是模拟真实的开发场景,写入application.yml配置文件中,通过定义一个类,然后指定配置文件,在阿里配置类中注入改实体类对象。如下图所示
@Data @AllArgsConstructor @NoArgsConstructor @Component @ConfigurationProperties("ali.msg") public class Ali { private String accessKeyId; private String accessKeySecret; private String signName; private String templateCode; }
然后需要随机生成数字,我这里也使得是hutool工具,需要加入该工具的jar包
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency>
该工具包含各种场景的工具,满足开发需求的很多场景,大家可以学习一下,随机生成的代码如下:
public static String codes(){ // 自定义纯数字的验证码(随机4位数字,可重复) RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); return String.valueOf(randomGenerator); }
生成一个从0到9随机组成的4位数。
然后就可以开始编写我们的真实开发环境的发送验证码
@GetMapping("/send") public R sentMsg(String phone){ //判断前端传过来的手机号是否正确 if (phone.equals("166x786xxxxx")){ //判断验证码是否已发送,防止恶意发送 if (redisTemplate.hasKey("code::"+phone)){ return new R(200,"请不要频繁点击",null); } try { //调用阿里云的接口并拿到前端传来的手机号 String code = SendMsgUtil.sendCode(phone); //把验证码存入到redis缓存中并设置过期时间 redisTemplate.opsForValue().set("code::"+phone,code,5, TimeUnit.MINUTES); return new R(200,"发送成功",null); } catch (Exception e) { throw new RuntimeException(e); } } return new R(200,"发送失败",null); }
@PostMapping("/login") public R login(@RequestBody LoginVo loginVo){ //拿到缓存中的验证码 String code = redisTemplate.opsForValue().get("code::" + loginVo.getPhone()); //拿到缓存中的手机号 String phone = loginVo.getPhone(); //判断手机号是否正确 if (phone.equals("16627865460")){ //判断验证码是否为空是否正确 if (StringUtils.hasText(loginVo.getCode())&&loginVo.getCode().equals(code)){ //删除缓存中的验证码,防止恶意登入 redisTemplate.delete("code::" + phone); return new R(200,"登入成功",null); }else { return new R(500,"登入失败",null); } } return new R(500,"登入失败",null); }
以上就是全部的登入过程,欢迎大家积极讨论。