谷粒商城-高级-58 -商城业务-认证服务-整合短信验证码

一、短信接口申请

阿里云短信接口申请

file

申请成功后,会拿到 appcode 码。

二、第三方接入短信

我们项目的 gulimall-third-party 微服务专门来处理和第三方交互相关的,所以,短信发送功能也集成在该模块。

创建发送短信文件:
com/atguigu/gulimall/thirdparty/component/SmsComponent.java

package com.atguigu.gulimall.thirdparty.component;

import com.atguigu.common.utils.HttpUtils;
import lombok.Data;
import org.apache.http.HttpResponse;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: kaiyi
 * @create: 2020-09-06 16:14
 */
@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
@Data
@Component
public class SmsComponent {

  private String host;
  private String path;
  private String templateId;
  private String sign;
  private Integer expireTime;  // 过期时间,几分钟后过期
  private String appcode;

  public void sendCode(String phone,String code) {
    String method = "POST";
    Map<String, String> headers = new HashMap<String, String>();
    //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
    headers.put("Authorization", "APPCODE " + appcode);
    //根据API的要求,定义相对应的Content-Type
    headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    Map<String, String> querys = new HashMap<String, String>();
    Map<String, String> bodys = new HashMap<String, String>();
    bodys.put("callbackUrl", "http://test.dev.esandcloud.com");
    bodys.put("channel", "0");
    bodys.put("mobile", phone);
    bodys.put("templateID", templateId);  // 短信模板ID,这里先写死,使用测试模板,正式模板需要自己申请。
    bodys.put("templateParamSet", "['"+code+"', '1']");

    try {
      /**
       * 重要提示如下:
       * HttpUtils请从
       * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
       * 下载
       *
       * 相应的依赖请参照
       * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
       */
      HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);

      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();
    }

  }

}

修改配置文件,增加SMS的相关配置:
gulimall-third-party/src/main/resources/application.yml

spring:
  #  配置nacos注册中心
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    alicloud:
      sms:
        host: https://edisim.market.alicloudapi.com
        path: /comms/sms/sendmsg
        templateId: "0000000"
        expireTime: 2  # 过期时间,分钟
        sign: 175622
        appcode: a14b1a0a9***************2d48
  application:
    name: gulimall-third-party
server:
  port: 30000
alibaba:
  cloud:
    access-key: LTAI4Fq************2aTCJ
    secret-key: Ueb6cWi*************tPXUqi
    oss:
      endpoint: oss-cn-heyuan.aliyuncs.com
      bucket: gulimall-corwien

创建控制器:
com/atguigu/gulimall/thirdparty/controller/SmsSendController.java

package com.atguigu.gulimall.thirdparty.controller;

import com.atguigu.common.utils.R;
import com.atguigu.gulimall.thirdparty.component.SmsComponent;
/**
 * @author: kaiyi
 * @create: 2020-09-06 18:01
 */
@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();
  }

}

测试发送:

 2020-09-06 19:27:48.275  INFO 40352 --- [           main] a.g.t.GulimallThirdPartyApplicationTests : Started GulimallThirdPartyApplicationTests in 12.81 seconds (JVM running for 15.998)
HTTP/1.1 200 OK [Date: Sun, 06 Sep 2020 11:27:49 GMT, Content-Type: application/x-www-form-urlencoded;charset=UTF-8, Content-Length: 121, Connection: keep-alive, Keep-Alive: timeout=25, Expires: 0, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, Set-Cookie: XSRF-TOKEN=8cb1f049-acba-455e-9890-a2554368d804; Path=/, X-XSS-Protection: 1; mode=block, Server: Kaede/3.5.3.481 (sh001uvm2), Pragma: no-cache, X-Frame-Options: DENY, X-Ca-Request-Id: 43228427-3096-41BB-9BBC-74EAB514B3CC, X-Content-Type-Options: nosniff] org.apache.http.conn.BasicManagedEntity@4451f60c
2020-09-06 19:27:49.872  INFO 40352 --- [      Thread-11] c.a.c.s.b.o.c.OssApplicationListener     : 1 OSSClients will be shutdown soon

三、认证中心调用

认证中心(gulimall-auth-server)通过Feign调用第三方微服务(gulimall-third-party)的短信发送功能。

创建 gulimall-auth-server/src/main/java/com/atguigu/gulimall/auth/feign/ThirdPartFeignService.java

 package com.atguigu.gulimall.auth.feign;

import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @author: kaiyi
 * @create: 2020-09-07 20:49
 */

@FeignClient("gulimall-third-party")
public interface ThirdPartFeignService {

  @GetMapping("/sms/sendcode")
  public R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code);

}

com/atguigu/gulimall/auth/controller/LoginController.java


 package com.atguigu.gulimall.auth.controller;

import com.atguigu.common.utils.R;
import com.atguigu.gulimall.auth.feign.ThirdPartFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.UUID;

/**
 * @author: kaiyi
 * @create: 2020-09-06 13:41
 */
@Controller
public class LoginController {

  @Autowired
  ThirdPartFeignService thirdPartFeignService;

  @ResponseBody
  @GetMapping("/sms/sendcode")
  public R sendCode(@RequestParam("phone") String phone) {
    String code = UUID.randomUUID().toString().substring(0, 6);

    thirdPartFeignService.sendCode(phone, code);
    return R.ok();
  }
}

为者常成,行者常至