12.認證服務-簡訊驗證碼
阿新 • • 發佈:2022-03-17
一、阿里雲簡訊服務
https://www.aliyun.com/product/sms?spm=5176.159202.J_8058803260.68.64ae6a56APLp1H
二、工具類 HttpUtils
或者直接下載:http://code.fegine.com/HttpUtils.zip
下載相應的依賴請參照 https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
相關jar包(非pom)直接下載:http://code.fegine.com/aliyun-jar.zip
三、相關配置
spring: cloud: nacos: discovery: server-addr: 192.168.163.131:8848 alicloud: sms: host: https://fesms.market.alicloudapi.com path: /sms/ skin: 1 sign: 175622 appcode: 93b7e19861a24c519a7548b17dc16d75
四、傳送驗證碼元件
package com.zsy.third.party.component; import com.zsy.common.utils.HttpUtils; import lombok.Data; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; /** * @Description: * @author: zhangshuaiyin * @createTime: 2020-06-27 09:39 **/ @ConfigurationProperties(prefix = "spring.cloud.alicloud.sms") @Data @Component public class SmsComponent { private String host; private String path; private String skin; private String sign; private String appcode; public void sendCode(String phone, String code) { String method = "GET"; Map<String, String> headers = new HashMap<>(); // 最後在header中的格式(中間是英文空格)為 Authorization:APPCODE 93b7e19861a24c519a7548b17dc16d75 headers.put("Authorization", "APPCODE " + appcode); Map<String, String> queries = new HashMap<String, String>(); queries.put("code", code); queries.put("phone", phone); queries.put("skin", skin); queries.put("sign", sign); //JDK 1.8示例程式碼請在這裡下載: http://code.fegine.com/Tools.zip try { HttpResponse response = HttpUtils.doGet(host, path, method, headers, queries); //System.out.println(response.toString());如不輸出json, 請開啟這行程式碼,列印除錯頭部狀態碼。 //狀態碼: 200 正常;400 URL無效;401 appCode錯誤; 403 次數用完; 500 API網管錯誤 //獲取response的body System.out.println(EntityUtils.toString(response.getEntity())); } catch (Exception e) { e.printStackTrace(); } } }
五、測試
@Test
public void sendSmsCode() {
smsComponent.sendCode("13838383838", "134531");
}
六、傳送簡訊介面
/**
* @author: zhangshuaiyin
* @createTime: 2020-06-27 10:04
**/
@Controller
@RequestMapping(value = "/sms")
public class SmsSendController {
@Resource
private SmsComponent smsComponent;
/**
* 提供給別的服務進行呼叫
* @param phone
* @param code
* @return
*/
@GetMapping(value = "/sendCode")
public R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code) {
//傳送驗證碼
smsComponent.sendCode(phone,code);
return R.ok();
}
}
七、介面防刷和驗證碼再次校驗
mall-auth-server LoginController.java
@ResponseBody
@GetMapping(value = "/sms/sendCode")
public R sendCode(@RequestParam("phone") String phone) {
//1、介面防刷
String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
if (!StringUtils.isEmpty(redisCode)) {
//活動存入redis的時間,用當前時間減去存入redis的時間,判斷使用者手機號是否在60s內傳送驗證碼
long currentTime = Long.parseLong(redisCode.split("_")[1]);
if (System.currentTimeMillis() - currentTime < 60000) {
//60s內不能再發
return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_CODE_EXCEPTION.getMsg());
}
}
//2、驗證碼的再次效驗 redis.存key-phone,value-code
int code = (int) ((Math.random() * 9 + 1) * 100000);
String codeNum = String.valueOf(code);
String redisStorage = codeNum + "_" + System.currentTimeMillis();
//存入redis,防止同一個手機號在60秒內再次傳送驗證碼
stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone,
redisStorage, 10, TimeUnit.MINUTES);
thirdPartFeignService.sendCode(phone, codeNum);
return R.ok();
}