手机发送验证码 - yiyanglij/yiyanglij.github.io GitHub Wiki

Controller

 @ApiOperation("手机获取验证码")
@GetMapping(value = "sendSmsCode")
@ApiImplicitParams({
        @ApiImplicitParam(name = "telephone", value = "手机号", required = true, dataType = "String"),
})
public String getMemberTest(String telephone) {
    String code=this.loginService.sendSmsCode(telephone);
    return  code;
}

Service

String sendSmsCode(String telephone);

ServiceImpl

@Override
public String sendSmsCode(String telephone) {
    AssertExt.matches("1\\d{10}", telephone, "不是有效手机号");
    String redisKey = REDIS_PREFIX + telephone;
    String code = this.stringRedisTemplate.opsForValue().get(redisKey);
    AssertExt.isTrue(code == null, "发送验证码过于频繁");
    code = RandomStringUtils.random(6, false, true);

    this.aliyunService.sendSms(telephone, code);


    this.stringRedisTemplate.opsForValue().set(redisKey, code, 1, TimeUnit.MINUTES);
    return code;
}

调用的方法Service

 Map sendSms(String telephone, String code);

调用的方法ServiceImpl

 @Override
public Map sendSms(String telephone, String code) {
	AssertExt.notBlank(telephone, "无效telephone");
	AssertExt.notBlank(code, "无效code");
	Map<String, String> params = new HashMap<>();
	params.put("PhoneNumbers", telephone);
	params.put("SignName", Constant.PLATFORM_NAME);
	params.put("TemplateCode", this.aliyunSmsProperties.getTemplateCode());
	params.put("Action", "SendSms");
	params.put("TemplateParam", String.format("{\"code\":\"%s\"}", code));
	return this.aliyunSmsHttp.get(params);
}

硅谷手机登陆实现思路

  1. 从loginVo获取输入的手机号,和验证码
  2. 判断手机号和验证码是否为空
  3. 判断手机验证码和输入的验证码是否一致
  4. 绑定手机号码
  5. 如果userinfo为空,进行正常手机登录
  6. 校验是否被禁用
  7. 判断是否第一次登陆,是:放回登陆信息->1用户名 2token信息 不是:直接登陆 *jwt生成token字符串

Api

 @PostMapping("login")
public Result login(@RequestBody LoginVo loginVo) {
    Map<String,Object> info = userInfoService.loginUser(loginVo);
    return Result.ok(info);
}

IuserInfoService

Map<String, Object> loginUser(LoginVo loginVo);

UserInfoServiceImpl

@Override
public Map<String, Object> loginUser(LoginVo loginVo) {
    //从loginVo获取输入的手机号,和验证码
    String phone = loginVo.getPhone();
    String code = loginVo.getCode();

    //判断手机号和验证码是否为空
    if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
        throw new YyghException(ResultCodeEnum.PARAM_ERROR);
    }

    //判断手机验证码和输入的验证码是否一致
    String redisCode = redisTemplate.opsForValue().get(phone);
    if(!code.equals(redisCode)) {
        throw new YyghException(ResultCodeEnum.CODE_ERROR);
    }

    //绑定手机号码
    UserInfo userInfo = null;
    if(!StringUtils.isEmpty(loginVo.getOpenid())) {
        userInfo = this.selectWxInfoOpenId(loginVo.getOpenid());
        if(null != userInfo) {
            userInfo.setPhone(loginVo.getPhone());
            this.updateById(userInfo);
        } else {
            throw new YyghException(ResultCodeEnum.DATA_ERROR);
        }
    }

    //如果userinfo为空,进行正常手机登录
    if(userInfo == null) {
        //判断是否第一次登录:根据手机号查询数据库,如果不存在相同手机号就是第一次登录
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",phone);
        userInfo = baseMapper.selectOne(wrapper);
        if(userInfo == null) { //第一次使用这个手机号登录
            //添加信息到数据库
            userInfo = new UserInfo();
            userInfo.setName("");
            userInfo.setPhone(phone);
            userInfo.setStatus(1);
            baseMapper.insert(userInfo);
        }
    }

    //校验是否被禁用
    if(userInfo.getStatus() == 0) {
        throw new YyghException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
    }

    //不是第一次,直接登录
    //返回登录信息
    //返回登录用户名
    //返回token信息
    Map<String, Object> map = new HashMap<>();
    String name = userInfo.getName();
    if(StringUtils.isEmpty(name)) {
        name = userInfo.getNickName();
    }
    if(StringUtils.isEmpty(name)) {
        name = userInfo.getPhone();
    }
    map.put("name",name);

    //jwt生成token字符串
    String token = JwtHelper.createToken(userInfo.getId(), name);
    map.put("token",token);
    return map;
}

发送手机验证码,将信息保存到Redis

 @GetMapping("send/{phone}")
public Result sendCode(@PathVariable String phone) {
    //从redis获取验证码,如果获取获取到,返回ok
    // key 手机号  value 验证码
    String code = redisTemplate.opsForValue().get(phone);
    if(!StringUtils.isEmpty(code)) {
        return Result.ok();
    }
    //如果从redis获取不到,
    // 生成验证码,
    code = RandomUtil.getSixBitRandom();
    //调用service方法,通过整合短信服务进行发送
    boolean isSend = msmService.send(phone,code);
    //生成验证码放到redis里面,设置有效时间
    if(isSend) {
        redisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);
        return Result.ok();
    } else {
        return Result.fail().message("发送短信失败");
    }
}

ImsmService

 //发送手机验证码
boolean send(String phone, String code);

//mq使用发送短信
boolean send(MsmVo msmVo);

MsmServiceImpl

@Override
public boolean send(String phone, String code) {
    //判断手机号是否为空
    if(StringUtils.isEmpty(phone)) {
        return false;
    }
    //整合阿里云短信服务
    //设置相关参数
    DefaultProfile profile = DefaultProfile.
            getProfile(ConstantPropertiesUtils.REGION_Id,
                    ConstantPropertiesUtils.ACCESS_KEY_ID,
                    ConstantPropertiesUtils.SECRECT);
    IAcsClient client = new DefaultAcsClient(profile);
    CommonRequest request = new CommonRequest();
    //request.setProtocol(ProtocolType.HTTPS);
    request.setMethod(MethodType.POST);
    request.setDomain("dysmsapi.aliyuncs.com");
    request.setVersion("2017-05-25");
    request.setAction("SendSms");

    //手机号
    request.putQueryParameter("PhoneNumbers", phone);
    //签名名称
    request.putQueryParameter("SignName", "我的谷粒在线教育网站");
    //模板code
    request.putQueryParameter("TemplateCode", "SMS_180051135");
    //验证码  使用json格式   {"code":"123456"}
    Map<String,Object> param = new HashMap();
    param.put("code",code);
    request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));

    //调用方法进行短信发送
    try {
        CommonResponse response = client.getCommonResponse(request);
        System.out.println(response.getData());
        return response.getHttpResponse().isSuccess();
    } catch (ServerException e) {
        e.printStackTrace();
    } catch (ClientException e) {
        e.printStackTrace();
    }
    return false;
}

//mq发送短信封装
@Override
public boolean send(MsmVo msmVo) {
    if(!StringUtils.isEmpty(msmVo.getPhone())) {
        boolean isSend = this.send(msmVo.getPhone(), msmVo.getParam());
        return isSend;
    }
    return false;
}

private boolean send(String phone, Map<String,Object> param) {
    //判断手机号是否为空
    if(StringUtils.isEmpty(phone)) {
        return false;
    }
    //整合阿里云短信服务
    //设置相关参数
    DefaultProfile profile = DefaultProfile.
            getProfile(ConstantPropertiesUtils.REGION_Id,
                    ConstantPropertiesUtils.ACCESS_KEY_ID,
                    ConstantPropertiesUtils.SECRECT);
    IAcsClient client = new DefaultAcsClient(profile);
    CommonRequest request = new CommonRequest();
    //request.setProtocol(ProtocolType.HTTPS);
    request.setMethod(MethodType.POST);
    request.setDomain("dysmsapi.aliyuncs.com");
    request.setVersion("2017-05-25");
    request.setAction("SendSms");

    //手机号
    request.putQueryParameter("PhoneNumbers", phone);
    //签名名称
    request.putQueryParameter("SignName", "我的谷粒在线教育网站");
    //模板code
    request.putQueryParameter("TemplateCode", "SMS_180051135");

    request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));

    //调用方法进行短信发送
    try {
        CommonResponse response = client.getCommonResponse(request);
        System.out.println(response.getData());
        return response.getHttpResponse().isSuccess();
    } catch (ServerException e) {
        e.printStackTrace();
    } catch (ClientException e) {
        e.printStackTrace();
    }
    return false;
}
⚠️ **GitHub.com Fallback** ⚠️