使用阿里云短信验证码API发送短信验证码(配置,获取短信验证码,注册,登录,密码重置)

获取阿里云短信验证码需要的配置信息。

如果是新用户,可以免费领取3个月,老用户的话就只能购买了,但是也不贵。

申请短信签名
申请短信签名
申请短信模板
申请短信模板

编写发送短信验证码的工具类

代码中我已经进行了详细的注释,也写了一个生成6位随机数字的方法.

如果有什么疑问,欢迎在评论里留言。

package com.imlee.examsys.utils;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;

/**
 * @Author imlee
 * @Date 2019-08-31 14:49
 *
 * 调用阿里云短信验证码 API
 * 进行手机号码的验证
 */

public class SendSms {

    //  自己账号的 accessKeyId
    private static final String accessKeyId = "";
    //  自己账号的 accessKeySecret
    private static final String accessKeySecret = "";
    //  自己账号的   短信签名名称
    private static final String signName = "";
    //  自己账号的   短信模板ID
    private static final String templateCode = "";

    /**
     *         发送短信验证码
     *
      * @param telephoneNumber  用户填写的手机号码
     * @return validateCode     该用户此次操作的短信验证码
     */
    public static String sendMessage(String telephoneNumber) {

        //  随机生成 6位 验证码
        String validateCode = String.valueOf((int)((Math.random() * 9 + 1) * 100000));

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        //  请求方式  POST(默认)
        request.setMethod(MethodType.POST);
        //  阿里云短信服务器(默认)
        request.setDomain("dysmsapi.aliyuncs.com");
        //  版本号(默认)
        request.setVersion("2017-05-25");
        //  执行动作  发送短信 (默认)
        request.setAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", telephoneNumber);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", "{\"code\":" + validateCode + "}");

        try {
            CommonResponse response = client.getCommonResponse(request);

            System.out.println(response.getData());

        } catch (ServerException e) {
            e.printStackTrace();
            return "抱歉,您的当前获取次数已达上限,请于下一个时段或明天再试!";
        } catch (ClientException e) {
            e.printStackTrace();
            return "系统异常,请重新获取!";
        }

        return validateCode;
    }

}


之前写的项目,和验证码相关的一些操作,将短信验证码保存到了redis中,使用它进行注册、登录、重置密码等操作。这个连载的代码都是自己写的,提供给需要的同学参考,如果有什么想要交流的,欢迎留言。

此处进行获取短信验证码的操作。


import com.imlee.examsys.pojo.JsonResult;
import com.imlee.examsys.pojo.User;
import com.imlee.examsys.service.UserService;
import com.imlee.examsys.utils.SendSms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 *      和验证码相关的后台接口
 *
 * @Author imlee
 * @Date 2019-09-02 10:10
 */
@CrossOrigin
@RestController
public class ValidateController {

    //  注入 Redis
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    /**
     *                      获取短信验证码
     *
     * @Author  imlee
     *
     * @param telephoneNumber   用户填写的手机号码
     * @return                  验证码发送成功的提示
     */
    @RequestMapping("/getCode.do")
    public JsonResult getCode(String telephoneNumber) {

        //  判断是否填写手机号码
        if (telephoneNumber == null) {
            //  未填写手机号码,返回失败提示
            return new JsonResult(0, "请输入手机号码!");
        }

        //  判断用户填写的手机号码是否合法
        if (!telephoneNumber.matches("^1(([358]\\d)|66|76|77|99)\\d{8}$")) {
            //  手机号码不合法,返回失败提示
            return new JsonResult(0, "手机号码不合法,请重新输入!");
        }

        //    将用的短信验证码保存到Redis中
        String validateCode = SendSms.sendMessage(telephoneNumber);

        //  判断获取短信验证码是否出现异常
        if (validateCode.length() != 6) {
            //  说明返回的不是验证码,而是异常信息
            return new JsonResult(0, validateCode);
        }

        //  将短信验证码保存到 Redis 中,有效期为5分钟
        //  key  : 手机号码
        //  value: 验证码
        redisTemplate.opsForValue().set(telephoneNumber, validateCode);
        redisTemplate.expire(telephoneNumber, 300, TimeUnit.SECONDS);

        return new JsonResult(1, "发送成功,请查收!");
    }
/**
*					接下来的代码是写在这里的
**/
}

下面的代码都是写在上面这个里面的,代码最后有注释。

这里是在注册时填写用户名后实时验证是否可用

这个代码是在用户在输入框中填写用户名后,异步请求后台进行查询,用户名是否可用。这个项目进行了跨域处理,在上面已经添加了@CrossOrigin注解了。


    /**
     *          注册账号时,在用户输入用户名之后,输入框失去焦点后立即查询数据库中是否存在此用户名
     *
     * @Author imlee
     * @param username
     * @return      返回查询结果、提示信息
     */
    @RequestMapping("/checkName.do")
    public JsonResult checkName(String username) {

        User user = userService.login(username);
        if (user == null) {

            if (username.matches("^[1-9a-zA-Z]{3,12}$")) {

                return new JsonResult(1, "用户名可以使用!");
            } else {

                return new JsonResult(0, "用户名不合法!");
            }

        }

        return new JsonResult(0, "用户名已存在!");
    }

使用短信验证码进行用户注册

我的理解是,在使用手机号码进行注册的时候,先使用手机号码进行“预注册”,判断手机号码是否已经注册,以及用户填写的短信验证码是否可用。


    /**
     *          注册账号第一步:使用手机号码进行预注册
     *
     * @Author  imlee
     *
     * @param telephoneNumber   用户填写的电话号码
     * @param telephoneCode     短信验证码
     * @return
     */
    @RequestMapping("/signUpFirst.do")
    public JsonResult signUp(String telephoneNumber, String telephoneCode) {

        User user = userService.signInByTelephoneNumber(telephoneNumber);
        if (user != null) {
            return new JsonResult(0, "此号码已注册,请直接登录!");
        }

        //  按照 手机号码 + 短信验证码 注册
        //      获取 保存在 redis 中的短信验证码
        String code = redisTemplate.opsForValue().get(telephoneNumber);

        //  判断短信验证码是否过期
        if (code == null || code.equals("")) {
            return new JsonResult(0, "验证码已过期,请重新获取!");
        } else {
            //  验证 用户输入的验证码和redis中保存的验证码是否一致
            if (telephoneCode.equals(code)) {

                //  验证码正确,执行注册逻辑
                int i = userService.signUpFirst(telephoneNumber);

                if (i != 1) {
                    //  返回受影响行数,不为1,即注册失败
                    return new JsonResult(0, "注册失败!");
                }

            } else {
                //  验证码错误,返回提示
                return new JsonResult(0, "验证码输入有误,请重新输入!");
            }
        }

        return new JsonResult(1, telephoneNumber);
    }

进行注册的信息填写,这里我在代码里写的验证码是图片验证码,前面第一步的验证码才是短信验证码。因为我的注册是两步完成的,填写手机号码和短信验证码后跳转到填写注册信息的页面。也就是说第一步的时候只是在数据库中写入一个手机号码,没有其它的信息,在第二个页面中补充完整。

    /**
     *          注册账号第二步:设置用户名和密码
     *
     * @Author  imlee
     * @param username          用户填写的用户名
     * @param password          用户填写的密码
     * @param telephoneNumber   用户填写的电话号码
     * @param validate          用户填写的验证码
     * @return
     */
    @RequestMapping("/signUp.do")
    public JsonResult signUp(String username, String password, String telephoneNumber, String validate) {

        //  获取 redis 中保存的验证码文字
        String codeStr = redisTemplate.opsForValue().get("codeStr");

        //  首先验证 验证码(忽略大小写)
        if (validate.equalsIgnoreCase(codeStr)) {

            //  执行注册逻辑
            //  先查询用户名是否存在
            User user = userService.login(username);

            //  判断用户名是否存在
            if (user != null) {
                //  用户名已存在
                return new JsonResult(0, "此用户名已存在,请使用其它用户名!");
            } else {
                //  用户名不存在,进行注册
                int i = userService.signUp(username, password, telephoneNumber);

                if (i != 1) {
                    //  返回受影响行数,不为1,即注册失败
                    return new JsonResult(0, "注册失败!");
                }
            }
        } else {

            //  验证码错误,返回提示
            return new JsonResult(0, "验证码输入有误,请重新输入!");
        }

        return new JsonResult(1, "注册成功!");
    }

短信验证码登录

我将短信验证码登录和用户名、密码登录,写在了一起。

    /**
     *      登录方法    1.使用账号 + 密码 + 文字验证码登录
     *                 2.使用手机号码 + 短信验证码登录
     *
     * @Author  imlee
     *
     * @param username          用户名
     * @param password          密码
     * @param validate          验证码
     * @param telephoneNumber   手机号码
     * @param telephoneCode     短信验证码
     * @return                  供前台使用的 Json 数据
     */
    @RequestMapping("/signIn.do")
    public JsonResult signIn(String username, String password, String validate, String telephoneNumber, String telephoneCode) {

        //  验证码非空或者不是null,说明使用的是账号 + 密码 + 验证码
        //      反之,说明使用的是,手机号码 + 短信验证码

        User user = null;

        if (validate != null && !validate.equals("")) {

            //  获取 redis 中保存的验证码文字
            String codeStr = redisTemplate.opsForValue().get("codeStr");

            //  首先验证 验证码(忽略大小写)
            //      验证码正确,再验证,账号、密码
            if (validate.equalsIgnoreCase(codeStr)) {

                //  执行登录逻辑
                user = userService.login(username);

                //  判断用户名是否存在
                if (user == null) {
                    return new JsonResult(0, "此用户名不存在,请核对后重新登录!");
                } else {

                    //  比对用户输入的密码和数据库中是否一致
                    if (!password.equals(user.getPassword())) {
                        return new JsonResult(0, "密码错误,请核对密码或用户名是否输入有误!");
                    }
                }
            } else {

                //  验证码错误,返回提示
                return new JsonResult(0, "验证码输入有误,请重新输入!");
            }
        } else {

            //  按照 手机号码 + 短信验证码 的逻辑登录
            //      获取 保存在 redis 中的短信验证码
            String code = redisTemplate.opsForValue().get(telephoneNumber);

            //  判断短信验证码是否过期
            if (code == null || code.equals("")) {
                return new JsonResult(0, "验证码已过期,请重新获取!");
            }

            //  验证 用户输入的验证码和redis中保存的验证码是否一致
            if (telephoneCode.equals(code)) {

                //  验证码正确,执行登录逻辑
                user = userService.signInByTelephoneNumber(telephoneNumber);

                if (user == null) {
                    return new JsonResult(0, "此号码未注册账号,如需注册请移步注册页面(验证码有效期5分钟)!");
                }

            } else {
                //  验证码错误,返回提示
                return new JsonResult(0, "验证码输入有误,请重新输入!");
            }
        }

        //  登录成功,返回 user 对象
        return new JsonResult(1, user);
    }

短信验证码重置密码

就不多介绍了,直接上代码了,全手工打造。这个连载到此就暂时结束了。欢迎留言交流!


    /**
     *          重置密码:第一步,查询手机号码是否存在
     *
     * @Author  imlee
     * @param telephoneNumber   手机号码
     * @param telephoneCode     短信验证码
     * @return
     */
    @RequestMapping("/resetPasswordFirst.do")
    public JsonResult resetPasswordFirst(String telephoneNumber, String telephoneCode) {


        User user = userService.signInByTelephoneNumber(telephoneNumber);
        if (user == null) {
            return new JsonResult(0, "此号码未注册,请核对是否输入有误!");
        }

        //  按照 手机号码 + 短信验证码 重置密码
        //      获取 保存在 redis 中的短信验证码
        String code = redisTemplate.opsForValue().get(telephoneNumber);

        //  判断短信验证码是否过期
        if (code == null || code.equals("")) {

            return new JsonResult(0, "验证码已过期,请重新获取!");

        } else {
            //  验证 用户输入的验证码和redis中保存的验证码是否一致
            if (!telephoneCode.equals(code)) {
                return new JsonResult(0, "验证码输入有误,请重新输入!");
            }
        }

        return new JsonResult(1, telephoneNumber);
    }

    /**
     *          重置密码:第二步,修改密码
     *
     * @Author imlee
     * @param password          新密码
     * @param validate          验证码
     * @param telephoneNumber   手机号码
     * @return
     */
    @RequestMapping("/resetPassword.do")
    public JsonResult resetPassword(String password, String validate, String telephoneNumber) {

        //  获取 redis 中保存的验证码文字
        String codeStr = redisTemplate.opsForValue().get("codeStr");

        //  首先验证 验证码(忽略大小写)
        if (validate.equalsIgnoreCase(codeStr)) {

            //  执行重置密码逻辑
            int i = userService.resetPassword(password, telephoneNumber);

            if (i != 1) {
                return new JsonResult(0, "重置失败!");
            }

        } else {
            //  验证码错误,返回提示
            return new JsonResult(0, "验证码输入有误,请重新输入!");
        }

        return new JsonResult(1, "重置成功!");
    }

  • 10
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值