短信接口提供商 Vue3问题:如何实现短信验证码登录?前后端!

文章浏览阅读2.7k次,点赞26次,收藏24次。点击发送验证码按钮,获取手机短信验证码。此时,发送验证码按钮进入倒计时状态,且不可被点击。成功获取到短信验证码并输入,点击登录按钮

前端功能问题系列文章,点击上方合集↑

序言

大家好,我是大澈!

本文约3400+字,整篇阅读大约需要4分钟。

本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。

如果您只需要解决问题,请阅读第一、二部分即可。

如果您有更多时间,进一步学习问题相关知识点,请阅读至第三部分。

1. 需求分析

点击发送验证码按钮,获取手机短信验证码。此时,发送验证码按钮进入倒计时状态,且不可被点击。

成功获取到短信验证码并输入,点击登录按钮,完成页面跳转。

图片

2. 实现步骤 2.1 准备工作

短信验证码登录功能的实现,借助了阿里云短信业务API,我们可以使用阿里云的短信服务向用户发送验证码、通知、营销等不同类型的短信。

总体实现步骤如下:

图片

下面是具体的代码实现,包括前端、后端两方面。

2.2编写前端代码

对于前端来说,所做的操作并不算多,无非是要实现点击发送短信验证码后的倒计时效果,以及两个接口的调用。

对于倒计时效果,就是利用了定时器,去控制发送验证码按钮的状态。

对于调用的两个接口,一个是发送短信接口,一个是短信验证及登录接口。

相关代码实例请继续往下看,每个地方基本都给大家做了详细的注释。

模版代码:

  
                                               0">          {{ countdown > 0 ? `重新发送(${countdown})` : '发送验证码' }}                            登录            

逻辑代码:

import {reactive, ref} from 'vue'import Axios from '../api/axios';import {ElMessage} from "element-plus";const dataForm = reactive({  phone: '123456',  code: '',})let isSendingCode = ref(false);let countdown = ref(0);// 发送验证码,调验证码接口const sendVerificationCode = () => {  // 检查手机号是否有效  // ...  // 调发送短信接口  Axios.get('/admin/send', {    params: {      phone: dataForm.phone,    }  })  .then(res => {    ElMessage.success(res.data)  })  .catch(error => {    console.error(error);  });  isSendingCode.value = true;  // 设置倒计时时间,这里假设为10秒  countdown.value = 10;  // 倒计时效果  const countdownInterval = setInterval(() => {    countdown.value--;    if (countdown.value  {  // 调发送短信接口  Axios.post('/admin/checkLogin', {    phoneNumber: dataForm.phone,    code: dataForm.code,  })  .then(res => {    ElMessage.success(res.data)  })  .catch(error => {    console.error(error);  });}

2.3编写后端接口

对于后端实现,要先引入阿里云短信业务依赖,再封装短信发送工具类,再编写两个接口,一个是发送短信接口,一个是短信验证及登录接口。

在发送短信接口业务层中,生成随机字符串,传入并调用短信发送工具类方法发送验证码,并把验证码存入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层代码:

/*** 发送短信*/@Overridepublic 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 "短信发送异常";}/*** 检验手机验证码并登录*/@Overridepublic String checkLogin(String phoneNumber, String code) {  //1.redis 验证码校验  String redisCode = redisTemplate.opsForValue().get(phoneNumber);  if (code.equals(redisCode)){      return "登入成功";  }  return "登入失败";}

当然,上述前端和后端代码的实现中,必然会存在一些缺陷,因为它只是一个实例,具体的实现还需要在项目中根据需求进行完善。

3. 问题详解 3.1 常见短信服务API文档地址整理

阿里云短信服务API文档地址:。

以下是一些其它常见短信服务供应商:

结语

建立这个平台的初衷:

原创文章,作者:筱凯,如若转载,请注明出处:https://www.jingyueyun.com/ask/915.html

(0)
筱凯筱凯
上一篇 2024 年 7 月 15 日
下一篇 2024 年 7 月 15 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

云产品限时秒杀。精选云产品高防服务器,500M大带宽限量抢购  >>点击进入