项目需要使用验证码的方式实现登录或者注册,想起之前yshop项目也用过阿里云的短信验证码,在此记录下如何接入项目。
xml
<!--引入aliyun依赖-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.4.1</version>
</dependency>
java
@Data
public class VerityParam {
@NotBlank(message = "手机号必填")
private String phone;
//验证码登录/注册
private String type;
}
java
/**
* 阿里云短信验证码
* @param param
* @return
*/
@AnonymousAccess
@PostMapping("/register/verify")
@ApiOperation(value = "短信验证码发送", notes = "短信验证码发送")
public ApiResult<String> verify(@Validated @RequestBody VerityParam param) {
//查询手机号记录是否存在
YxUser yxUser = userService.getOne(Wrappers.<YxUser>lambdaQuery()
.eq(YxUser::getPhone,param.getPhone()),false);
//手机号存在且为注册操作
if (SmsTypeEnum.REGISTER.getValue().equals(param.getType()) && ObjectUtil.isNotNull(yxUser)) {
return ApiResult.fail("手机号已注册");
}
//手机号不存在且为登录操作
if (SmsTypeEnum.LOGIN.getValue().equals(param.getType()) && ObjectUtil.isNull(yxUser)) {
return ApiResult.fail("账号不存在");
}
String codeKey = "code_" + param.getPhone();
//6位数随机验证码
String code = RandomUtil.randomNumbers(ShopConstants.YSHOP_SMS_SIZE);
//多租户系统确认租户
String tenantId = TenantContextHandler.getTenantId();
//使用redis存储验证码
redisUtil.set(tenantId + ":" + codeKey, code, ShopConstants.YSHOP_SMS_REDIS_TIME);
//发送阿里云短信
JSONObject json = new JSONObject();
json.put("code",code);
try {
SmsUtils.sendSms(param.getPhone(),json.toJSONString());
} catch (ClientException e) {
redisUtil.del(codeKey);
e.printStackTrace();
return ApiResult.ok("发送失败:"+e.getErrMsg());
}
return ApiResult.ok("发送成功,请注意查收");
}
java
@Slf4j
@Configuration
public class SmsUtils {
private static RedisUtils redisUtils;
@Autowired
public SmsUtils(RedisUtils redisUtils){
SmsUtils.redisUtils = redisUtils;
}
/**
* 发送短信
* @param phoneNumbers 手机号
* @param templateParam 短信模板变量对应的实际值,JSON格式
* accessKeyId、secret、sign(SignName)需要自行设置
*/
public static void sendSms(String phoneNumbers, String templateParam) throws ClientException {
//租户
String tenantId = TenantContextHandler.getTenantId();
//根据租户从redis中取相应的值
String regionId = redisUtils.getY(tenantId + ":" +"sms_region");
String accessKeyId = redisUtils.getY(tenantId + ":" + "sms_access_key");
String accessKeySecret = redisUtils.getY(tenantId + ":" +"sms_access_secret");
String sign = redisUtils.getY(tenantId + ":" +"sms_sign");
String templateId = redisUtils.getY(tenantId + ":"+ "sms_templateId");
//链接阿里云
DefaultProfile profile = DefaultProfile.getProfile(
regionId,
accessKeyId,
accessKeySecret);
//构建成客户端
IAcsClient client = new DefaultAcsClient(profile);
//构建请求
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
//区域
request.putQueryParameter("RegionId", regionId);
//手机号码
request.putQueryParameter("PhoneNumbers", phoneNumbers);
//签名名称
request.putQueryParameter("SignName", sign);
//模板的code
request.putQueryParameter("TemplateCode", templateId);
//构建一个短信验证码
request.putQueryParameter("TemplateParam", templateParam);
//向阿里云请求发送验证码
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
}
}
java
/**
* 验证码登陆
*
* @param loginParam
* @return
*/
@AnonymousAccess
@PostMapping(value = "/login/captcha")
public ApiResult logincaptcha(@Validated @RequestBody HLoginParam loginParam) {
//去请求原有的逻辑获取用户信息
ApiResult<YxUser> yxUserApiResult = remoteMemberUserService.HLogin(loginParam);
//用户不存在
if (yxUserApiResult.getStatus() != 200) {
throw new YshopException(yxUserApiResult.getMsg());
}
System.out.println(loginParam);
//租户
String tenantId = TenantContextHandler.getTenantId();
//查询redis中是否有验证码记录
Object codeObj = redisUtil.get(tenantId + ":" + "code_" + loginParam.getUsername());
if (codeObj == null) {
return ApiResult.fail("请先获取验证码");
}
String code = codeObj.toString();
//比对redis中和输入的验证码
if (!StrUtil.equals(code, loginParam.getPassword())) {
return ApiResult.fail("验证码错误");
}
return getCaptchaMapApiResult(yxUserApiResult,loginParam.getPassword());
}