前端功能问题系列文章,点击上方合集↑
大家好,我是大澈!
本文约3400+
字,整篇阅读大约需要4分钟。
本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。
如果您只需要解决问题,请阅读第一、二部分即可。
如果您有更多时间,进一步学习问题相关知识点,请阅读至第三部分。
点击发送验证码按钮,获取手机短信验证码。此时,发送验证码按钮进入倒计时状态,且不可被点击。
成功获取到短信验证码并输入,点击登录按钮,完成页面跳转。
短信验证码登录功能的实现,借助了阿里云短信业务API,我们可以使用阿里云的短信服务向用户发送验证码、通知、营销等不同类型的短信。
总体实现步骤如下:
创建阿里云账号
:如果您还没有阿里云账号,需要先注册一个账号并完成身份验证。
开通短信服务
:登录阿里云控制台,找到短信服务并进行开通,然后完善相关信息,包括资质、签名、模板等,最后还需要购买短信套餐包。
这里解释一下两个概念:
短信签名
:短信签名是您发送短信时用于展示发送方身份的标识,需要在阿里云短信控制台进行申请和审核。
短信模板
:短信模板是您发送短信时所使用的短信内容模板,需要在阿里云短信控制台进行申请和审核。
获取API凭证
:在阿里云控制台中,创建 AccessKey,并确保该密钥对拥有短信发送的权限。
编写后端接口调用对应API
:使用选择的编程语言和相关 SDK,调用阿里云短信业务API中相应的接口,如发送短信、查询发送记录等。
编写前端代码
:发送短信并验证登录。
下面是具体的代码实现,包括前端、后端
两方面。
对于前端来说,所做的操作并不算多,无非是要实现点击发送短信验证码后的倒计时效果,以及两个接口的调用。
对于倒计时效果,就是利用了定时器,去控制发送验证码按钮的状态。
对于调用的两个接口,一个是发送短信接口,一个是短信验证及登录接口。
相关代码实例请继续往下看,每个地方基本都给大家做了详细的注释。
模版代码:
0">
{{ countdown > 0 ? `重新发送(${countdown})` : '发送验证码' }}
登录
逻辑代码:
对于后端实现,要先引入阿里云短信业务依赖,再封装短信发送工具类,再编写两个接口,一个是发送短信接口,一个是短信验证及登录接口。
在发送短信接口业务层中,生成随机字符串,传入并调用短信发送工具类方法发送验证码,并把验证码存入Redis
中。
在短信验证及登录接口业务层中,将前端传过来的验证码与Redis
中存的验证码进行比较,校验成功执行下一步登录操作。
相关代码实例请继续往下看,每个地方基本都给大家做了详细的注释。
Pom.xml
中引入依赖代码:
org.springframework.boot
spring-boot-starter-data-redis
com.aliyun
aliyun-java-sdk-core
4.6.0
com.aliyun
aliyun-java-sdk-dysmsapi
1.1.0
com.alibaba
fastjson
1.2.76
短信发送服务工具类代码:
package com.dache.base.common.util;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import java.util.HashMap;
/**
* @Description 短信发送服务
*/
public class SmsUtil {
public static String toSendMes(String phoneNumber,String code) {
//1.连接阿里云
/**
"", // The region ID 地区标识
"", // The AccessKey ID of the RAM account RAM账户的AccessKey ID 阿里云账号可查
"", // The AccessKey Secret of the RAM account RAM 账户的 AccessKey Secret 阿里云账号可查
**/
DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", "your-access-key-id", "your-access-key-secret");
IAcsClient client = new DefaultAcsClient(profile);
//2.构建请求 自定义参数
SendSmsRequest request = new SendSmsRequest();
//接收短信的手机号码
request.setPhoneNumbers(phoneNumber);
//短信签名名称
request.setSignName("阿里云短信测试");
//短信模板CODE
request.setTemplateCode("SMS_154SECRET9");
//模版内容:您正在使用阿里云短信测试服务,体验验证码是:${code},如非本人操作,请忽略本短信!
//短信模板变量对应的实际值
//("{\"code\":\"1234\"}");
HashMap param=new HashMap<>();
param.put("code",code);
request.setTemplateParam(JSONObject.toJSONString(param));
SendSmsResponse response = new SendSmsResponse();
try {
//3.发送请求
response = client.getAcsResponse(request);
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
//短信成功返回json { "RequestId": "614048FB-0619-4439-A1D5-AA8B218A****", "Message": "OK", "BizId": "386715418801811068^0", "Code": "OK"}
return response.getMessage();
}
}
接口Controller
层代码:
/**
* 发送短信
*/
@ApiOperation(value = "发送短信")
@GetMapping("/send")
public CommonResult toSendMessage(@RequestParam("phone") String phone){
String message = adminService.toSendMessage(phone);
return CommonResult.success(message);
}
/**
* 检验验证码和密码,校验成功后登录
*/
@ApiOperation(value = "检验验证码和密码,校验成功后登录")
@PostMapping("/checkLogin")
public CommonResult checkLogin(@RequestBody ToCheckLoginDTO toCheckLogin){
String checkLogin = adminService.checkLogin(toCheckLogin.getPhoneNumber(), toCheckLogin.getCode());
// 省略用户密码加密校验
// ...
// 省略JWT认证
// ...
return CommonResult.success(checkLogin);
}
接口Service
层代码:
/**
* 发送短信
*/
@Override
public String toSendMessage(String phoneNumber) {
//扩展 可以验证该电话号码是否注册
//1.判定验证码是否过期
String code = redisTemplate.opsForValue().get(phoneNumber);
if (!StringUtils.isEmpty(code)){
return phoneNumber+":"+"验证码未过期";
}
//2.已过期/无验证码 生成验证码
//随机生成字符串 做验证码
int toCode = (int) (Math.random() * (50000 - 40000) + 40000);
code=Integer.toString(toCode);
String toSendMes = SmsUtil.toSendMes(phoneNumber, code);
if (ComConstants.OK.equals(toSendMes)){
//redis 中存放 5分钟过期
redisTemplate.opsForValue().set(phoneNumber,code,ComConstants.NUM_FIVE, TimeUnit.MINUTES);
//3.发送短信
return "短信发送成功";
}
return "短信发送异常";
}
/**
* 检验手机验证码并登录
*/
@Override
public String checkLogin(String phoneNumber, String code) {
//1.redis 验证码校验
String redisCode = redisTemplate.opsForValue().get(phoneNumber);
if (code.equals(redisCode)){
return "登入成功";
}
return "登入失败";
}
当然,上述前端和后端代码的实现中,必然会存在一些缺陷,因为它只是一个实例
,具体的实现还需要在项目中根据需求进行完善。
阿里云短信服务API文档地址:https://help.aliyun.com/document_detail/101414.html
。
以下是一些其它常见短信服务供应商:
腾讯云短信服务API:腾讯云提供了短信服务API,用于发送短信验证码和推广短信。文档地址:https://cloud.tencent.com/document/product/382
。
云片网短信API:云片网是国内的一家短信服务提供商,他们提供了简单易用的短信API接口,用于发送验证码、通知短信等。文档地址:https://www.yunpian.com/doc/zh_CN/introduction/index.html
。
极光短信API:极光推送是一家提供多种推送服务的服务提供商,其中包括短信推送服务。他们提供了短信API,可以用于发送短信验证码和通知短信。文档地址:https://docs.jiguang.cn/jpush/server/push/rest_api_v3_sms/
。
建立这个平台的初衷:
打造一个仅包含前端问题的问答平台,让大家高效搜索处理同样问题。
通过不断积累问题,一起练习逻辑思维,并顺便学习相关的知识点。
遇到难题,遇到有共鸣的问题,一起讨论,一起沉淀,一起成长。
感谢关注微信公众号:“程序员大澈”,然后加入问答群
,让我们一起解决实现所有BUG!