近况
害,软考学不动啊,我感觉自己连学习都不会了,难道看看别人的软考博客,看几道例题就算学会了?
如果是自己把别人的笔记再整理一下的话,又觉得自己是在自我感动,对学习知识本身没什么用处
所以学习到底怎么学,又有可能是我想的太多做的太少,确实,现在的自己感觉太没有动力了,没有激情
牛逼的人对生活总是充满着激情,如果是因为提升自己才能收获激情,那我就是很久没有提升自己了
长时间的感觉没有提升,自然对于生活没有动力,这个星期六星期天一定要去学习,一定要有收获啊!!!
今天再水一篇关于配置阿里云的短信服务的,短信服务在很多场景都用到过,最常见的场景就是登录,注册,找回密码
正好公司让我去实现这个需求,所以去学习了一下怎么使用阿里云的短信服务
整个流程思路:
1.用户输入手机号,点击发送验证码
2.后端接收到请求,生成一个随机数,将该手机号和随机数保存在redis中,过期时间配置在配置类上
如果redis数据保存成功则调用阿里云短信接口发送短信,如果失败,则通知前端
根据返回json中body的code字段来判断成功还是失败
3.前端收到发送成功的结果后,用户会收到短信,用户输入验证码,前端将该用户的手机号和用户输入的验证码都发送到后端
后端根据用户手机号从redis中查询存在redis中的验证码,如果查询为空,则可能验证码过期,再将该验证码与用户输入的验证码进行对比,判断是否输入正确。
调用阿里云发送短信接口返回的数据,如果失败,则body中code为其他,但是statusCode值仍为200.

下面是配置阿里云短信服务流程
登录阿里云,申请短信签名和模板
申请通过后,我们需要的是签名名称和模板CODE两个字段的值,搞定后,需要再去配置一个阿里云AccessKey AccessKey相当于token,通过api请求阿里的接口就需要这个accessKey,页面右上角鼠标悬浮就能看到AccessKey管理
导入依赖
<dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>2.0.23</version> </dependency>
在项目配置文件上填上上面配置,并写好相应的配置类
application.yaml
jeecg : sms-config: #阿里云配置 accessKeyId: ${ACCESS_KEY_ID:xxxxxxxxxxx} accessKeySecret: ${ACCESS_KEY_SECRET:xxxxxxxxxxx} #短信模板 templateCode: ${TEMPLATE_CODE:xxxxxxxx} #短信签名 signName: ${SIGN_NAME:xxxxxxxxx} #验证码有效时间,单位默认为分钟 validTime: ${VALID_TIME:5}
SmsSendConfig
@Data @Configuration @ConfigurationProperties(prefix = "jeecg.sms-config") public class SmsSendConfig { /** * 访问阿里云的公钥 */ private String accessKeyId; /** * 访问阿里云的私钥 */ private String accessKeySecret; /** * 模板标识 */ private String templateCode; /** * 短信签名名称 */ private String signName; /** * 验证码有效时间,单位默认分钟 * @return * @throws Exception */ private Integer validTime; @Bean("SMSClient") public Client createClient() throws Exception{ Config config = new Config() .setAccessKeyId(accessKeyId) .setAccessKeySecret(accessKeySecret) .setEndpoint("dysmsapi.aliyuncs.com"); return new Client(config); } }
LoginController
@Autowired private SmsSendConfig smsSendConfig; @Autowired @Qualifier("SMSClient") private Client smsClient; private String getRandomString(Integer num){ String alphanumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; StringBuilder sb = new StringBuilder(num); SecureRandom random = new SecureRandom(); for (int i = 0; i < num; i++) { sb.append(alphanumeric.charAt(random.nextInt(alphanumeric.length()))); } return sb.toString(); } @ApiOperation("发送短信接口") @RequestMapping(value = "/sendSMS", method = RequestMethod.POST) public Result<Object> sendSMS(@RequestBody JSONObject jsonObject){ //0.参数获取和手机号格式校验 String phone = jsonObject.get("phone").toString(); //手机号模式,0:登录,2:忘记密码 String mode = jsonObject.get("mode").toString(); if (ObjectUtil.isEmpty(phone)|| !phone.matches(phoneRegex)){ return Result.error("手机号码格式不正确"); } //1.登录和忘记密码都必须要求用户已经绑定手机号,目前系统没有注册功能 SysUser sysUser = sysUserService.getUserByPhone(phone); if (ObjectUtil.isEmpty(sysUser)){ return Result.error("该用户不存在或未绑定手机号"); } String redisKey = phone+"-"+mode; //检查验证码是否有效,有效则直接返回 Object object = redisUtil.get(redisKey); if (object != null) { return Result.error("当前验证码仍然有效!"); } //2.生成验证码code,配置必要的请求参数 HashMap<String, String> map = new HashMap<>(); String code = getRandomString(6); map.put("code",code); String param = JSONObject.toJSONString(map); SendSmsRequest sendSmsRequest = new SendSmsRequest(); sendSmsRequest .setPhoneNumbers(phone) .setSignName(smsSendConfig.getSignName()) .setTemplateCode(smsSendConfig.getTemplateCode()) .setTemplateParam(param); //3.发送验证码 try { SendSmsResponse sendSmsResponse = smsClient.sendSms(sendSmsRequest); if (ObjectUtil.equals(sendSmsResponse.getBody().getCode(),200)){ redisTemplate.opsForValue().set(redisKey,code,smsSendConfig.getValidTime(),TimeUnit.MINUTES); return Result.OK("验证码发送成功"); } }catch (TeaException error) { // 如有需要,请打印 error com.aliyun.teautil.Common.assertAsString(error.message); } catch (Exception _error) { TeaException error = new TeaException(_error.getMessage(), _error); // 如有需要,请打印 error com.aliyun.teautil.Common.assertAsString(error.message); } return Result.error("短信验证码发送失败,请稍后重试"); }