如果是新用户,可以免费领取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, "重置成功!");
}