13Redis--Mobile phone verification code function--Alibaba cloud implementation

content

Redis implements mobile phone verification code

9.1. Implementation principle

9.2. Implementation

1. A tool to verify whether the mobile phone number is legal

2. Tools for generating verification codes

3. SMS Microservice Controller

4. SMS Microservice Service Layer

5. User registration microservice Controller

6. User registration microservice Service

9.3. Testing

1. Use the SMS micro service to send the verification code to the specified mobile phone number

2. View Redis cache and SMS

3. Open the user center microservice for testing

4. Results


Redis implements mobile phone verification code ---- not completed

Learn about Alibaba Cloud's user permission operations

1. Enable sub-users

2. Create a new user group (set the add permission sms)

3. Create a user (specific account for operation)

4. Get AccessKey (id, password) 

Activate Alibaba Cloud SMS Service

9.1. Implementation principle

  • Use tools to generate 4-digit or 6-digit verification codes
  • After verifying that the mobile phone number is valid, send the verification code through the SMS microservice
  • The mobile phone number is used as the key, the verification code is stored in redis as the value, and an expiration time is set
  • When the user logs in/registers, the verification code is retrieved from redis through the key (mobile phone number)
  • Compare the verification code. If it matches, the login/registration is passed, and the key-value in redis is randomly deleted.

9.2. Implementation

1. A tool to verify whether the mobile phone number is legal

 
 
  1. public class FormUtils {
  2. private static Pattern NUMBER_PATTERN = Pattern.compile("^[1][3,4,5,7,8,9][0-9]{9}$");
  3. /**
  4. * 手机号验证
  5. */
  6. public static boolean isMobile(String str) {
  7. //验证手机号的正则表达式
  8. return NUMBER_PATTERN.matcher(str).matches();
  9. }
  10. }

2. Tools for generating verification codes

 
 
  1. public class RandomUtils {
  2. private static final Random random = new Random();
  3. private static final DecimalFormat fourdf = new DecimalFormat("0000");
  4. private static final DecimalFormat sixdf = new DecimalFormat("000000");
  5. public static String getFourBitRandom() {
  6. return fourdf.format(random.nextInt(10000));
  7. }
  8. public static String getSixBitRandom() {
  9. return sixdf.format(random.nextInt(1000000));
  10. }
  11. /**
  12. * 给定数组,抽取n个数据
  13. * @param list
  14. * @param n
  15. * @return
  16. */
  17. public static ArrayList getRandom(List list, int n) {
  18. Random random = new Random();
  19. HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
  20. // 生成随机数字并存入HashMap
  21. for (int i = 0; i < list.size(); i++) {
  22. int number = random.nextInt(100) + 1;
  23. hashMap.put(number, i);
  24. }
  25. // 从HashMap导入数组
  26. Object[] robjs = hashMap.values().toArray();
  27. ArrayList r = new ArrayList();
  28. // 遍历数组并打印数据
  29. for (int i = 0; i < n; i++) {
  30. r.add(list.get((int) robjs[i]));
  31. System.out.print(list.get((int) robjs[i]) + "\t");
  32. }
  33. System.out.print("\n");
  34. return r;
  35. }
  36. }

3. SMS Microservice Controller

 
 
  1. @Slf4j
  2. @CrossOrigin
  3. @RestController
  4. @Api(tags = "短信管理控制器")
  5. @RequestMapping("/api/sms")
  6. public class ApiSmsController {
  7. @Autowired
  8. private SmsService smsService;
  9. @Autowired
  10. private RedisTemplate redisTemplate;
  11. /***
  12. * 根据传入的手机号来生成并发送验证码
  13. * 并将验证码存入redis缓存
  14. * @param mobile 手机号
  15. * @return
  16. */
  17. @GetMapping("send/{mobile}")
  18. @ApiOperation("一个用于生成验证码,并将验证码存入redis中的接口")
  19. public R getCode(@PathVariable("mobile") String mobile) throws ClientException {
  20. //0 校验手机号是否合法
  21. if(StringUtils.isBlank(mobile) || !FormUtils.isMobile(mobile)) {
  22. //如果手机号为空或手机号不合法
  23. log.error("手机号不合法!");
  24. // new GrainException(ResultCodeEnum.LOGIN_MOBILE_ERROR);
  25. return R.error().message("手机号不正确!").code(28001);
  26. }
  27. //1 使用工具类生成生成验证码
  28. String checkCode = RandomUtils.getSixBitRandom();
  29. //2 发送验证码
  30. smsService.send(mobile,checkCode);
  31. //3 存储验证码到redis
  32. //使用redisTemplate,使用手机号作为键,保存时长为5分钟
  33. redisTemplate.opsForValue().set(mobile,checkCode,5, TimeUnit.MINUTES);
  34. return R.ok().message("短信发送成功!");
  35. }
  36. }

4. SMS Microservice Service Layer

 
 
  1. @Slf4j
  2. @Service
  3. public class SmsServiceImpl implements SmsService {
  4. @Autowired
  5. private SmsProperties smsProperties;
  6. @Override
  7. public void send(String mobile, String checkCode) throws ClientException, ClientException {
  8. //调用短信发送SDK,创建client对象
  9. DefaultProfile profile = DefaultProfile.getProfile(
  10. smsProperties.getRegionId(),
  11. smsProperties.getKeyId(),
  12. smsProperties.getKeySecret());
  13. IAcsClient client = new DefaultAcsClient(profile);
  14. //组装请求参数
  15. CommonRequest request = new CommonRequest();
  16. request.setSysMethod(MethodType.POST);
  17. request.setSysDomain("dysmsapi.aliyuncs.com");
  18. request.setSysVersion("2017-05-25");
  19. request.setSysAction("SendSms");
  20. request.putQueryParameter("RegionId", smsProperties.getRegionId());
  21. request.putQueryParameter("PhoneNumbers", mobile);
  22. request.putQueryParameter("SignName", smsProperties.getSignName());
  23. request.putQueryParameter("TemplateCode", smsProperties.getTemplateCode());
  24. Map<String, Object> param = new HashMap<>();
  25. param.put("code", checkCode);
  26. //将包含验证码的集合转换为json字符串
  27. Gson gson = new Gson();
  28. request.putQueryParameter("TemplateParam", gson.toJson(param));
  29. //发送短信
  30. CommonResponse response = client.getCommonResponse(request);
  31. //得到json字符串格式的响应结果
  32. String data = response.getData();
  33. //解析json字符串格式的响应结果
  34. HashMap<String, String> map = gson.fromJson(data, HashMap.class);
  35. String code = map.get("Code");
  36. String message = map.get("Message");
  37. //配置参考:短信服务->系统设置->国内消息设置
  38. //错误码参考:
  39. //https://help.aliyun.com/document_detail/101346.html?spm=a2c4g.11186623.6.613.3f6e2246sDg6Ry
  40. //控制所有短信流向限制(同一手机号:一分钟一条、一个小时五条、一天十条)
  41. if ("isv.BUSINESS_LIMIT_CONTROL".equals(code)) {
  42. log.error("短信发送过于频繁 " + "【code】" + code + ", 【message】" + message);
  43. throw new GrainException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL);
  44. }
  45. if (!"OK".equals(code)) {
  46. log.error("短信发送失败 " + " - code: " + code + ", message: " + message);
  47. throw new GrainException(ResultCodeEnum.SMS_SEND_ERROR);
  48. }
  49. }
  50. }

5. User registration microservice Controller

 
 
  1. @Slf4j
  2. @CrossOrigin
  3. @RestController
  4. @Api(tags = "会员管理控制器")
  5. @RequestMapping("/api/ucenter/member")
  6. public class ApiMemberController {
  7. @Autowired
  8. private MemberService memberService;
  9. @ApiOperation("会员注册")
  10. @PostMapping("register")
  11. public R register(@RequestBody RegisterVo registerVo) {
  12. memberService.register(registerVo);
  13. return R.ok().message("注册成功!");
  14. }
  15. }

6. User registration microservice Service

 
 
  1. @Service
  2. public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
  3. @Autowired
  4. private RedisTemplate redisTemplate;
  5. @Autowired
  6. private MemberMapper memberMapper;
  7. @Override
  8. public void register(RegisterVo registerVo) {
  9. String nickname = registerVo.getNickname();
  10. String mobile = registerVo.getMobile();
  11. String code = registerVo.getCode();
  12. String password = registerVo.getPassword();
  13. if(StringUtils.isBlank(mobile) || !FormUtils.isMobile(mobile)) {
  14. throw new GrainException(ResultCodeEnum.LOGIN_MOBILE_ERROR);
  15. }
  16. if(StringUtils.isBlank(nickname) || StringUtils.isBlank(password) || StringUtils.isBlank(code)) {
  17. throw new GrainException(ResultCodeEnum.PARAM_ERROR);
  18. }
  19. //校验验证码
  20. String checkCode = (String)redisTemplate.opsForValue().get(mobile);
  21. if(!StringUtils.equals(code,checkCode)) {
  22. //如果用户输入验证码和redis中验证码不相等
  23. //校验失败
  24. throw new GrainException(ResultCodeEnum.CODE_ERROR);
  25. }
  26. //判断用户手机号是否注册
  27. QueryWrapper<Member> memberQueryWrapper = new QueryWrapper<>();
  28. memberQueryWrapper.eq("mobile",mobile);
  29. Integer result = memberMapper.selectCount(memberQueryWrapper);
  30. if(result > 0) {
  31. throw new GrainException(ResultCodeEnum.REGISTER_MOBLE_ERROR);
  32. }
  33. //注册
  34. Member member = new Member();
  35. member.setNickname(nickname);
  36. member.setMobile(mobile);
  37. //密码需要加密
  38. member.setPassword(MD5.encrypt(password));
  39. member.setAvatar("http://tiebapic.baidu.com/forum/w%3D580/sign=21e19fd45010b912bfc1f6f6f3fcfcb5/c0d5d04b20a44623e5077d0d8f22720e0ef3d78e.jpg");
  40. member.setDisabled(false);
  41. memberMapper.insert(member);
  42. //将redis缓存中的验证码删除
  43. redisTemplate.delete(mobile);
  44. }
  45. }

9.3. Testing

Start SMS microservice and user registration microservice, and use Swagger for testing

1. Use the SMS micro service to send the verification code to the specified mobile phone number

Uploading...Reupload canceled

2. View Redis cache and SMS

Short message

3. Open the user center microservice for testing

4. Results

swagger prompts that the registration is successful

The key-value pair is deleted from the redis cache

database

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324144248&siteId=291194637