精华内容
下载资源
问答
  • Redis实现session共享(基于手机短信验证码
    2022-04-19 21:50:18

    1.点击发送验证码

    1.1校验手机格式 如果错误则返回

    1.2生成6位随机数验证码

    1.3把验证码保存到redis并设置过期时间 以手机号码作为key 短信号码作为value

    1.4发送到控制台

    public Result sendCode(String phone, HttpSession session) {
            //1,校验手机号
            if(RegexUtils.isPhoneInvalid(phone)){
                //2,如果不符合,返回错误信息
                return  Result.fail("手机号格式错误");
            }
            //3,符合,生成验证码
            String code = RandomUtil.randomNumbers(6);
            //4.保存验证码到redis  有效期两分钟 set key value ex 120
            stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);
            //5,发送验证码
            log.debug("发送短信验证码成功,验证码:"+code);
            //返回ok
            return Result.ok();
        }

    2.登录

    2.1校验手机号

    2.2从redis获取验证码并校验

    2.3如果一致,查询数据库如果不存在就创建然后保存

    2.4随机生成token

    2.5把user转化为map

    2.6把userMap信息存入redis(以token为key) hashset

    2.7设置token(key)有效时期

    2.8把token返回给浏览器

    public Result login(LoginFormDTO loginForm, HttpSession session) {
            String phone = loginForm.getPhone();
            //1,校验手机号
            if(RegexUtils.isPhoneInvalid(phone)){
                //2,如果不符合,返回错误信息
                return  Result.fail("手机号格式错误");
            }
            //3,从redis获取验证码并校验
            String sessionCode =stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);
            String code = loginForm.getCode();
            if(sessionCode==null||!sessionCode.equals(code)){
                //3,不一致,报错
                return Result.fail("验证码错误");
            }
            //4,一致,根据手机号查询用户  select *from tb_user where phone =?
            User user = query().eq("phone", phone).one();
            //5,判断用户是否存在
            if(user==null){
                //6,不存在 创建用户并保存
                user=creteUserWithPhone(phone);
            }
            //TODO 7,存在,保存用户到redis中
            //TODO 7.1 随机生成token
            String token = UUID.randomUUID().toString();
            //TODO 7.2 将User对象转为hash储存
            UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
            Map<String, Object> map = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                    CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
            //TODO 7.3 储存user到redis
            String tokenKey=LOGIN_USER_KEY+token;
            stringRedisTemplate.opsForHash().putAll(tokenKey,map);
            //设置token有效期
            stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL,TimeUnit.MINUTES);
    ​
            //TODO 7.4返还token
            return Result.ok(token);
        }

    3.token刷新机制 通过拦截器

    3.1通过request拿到token

    3.2如果token为空直接返回 进入二层拦截器

    3.3通过token拿到redis中的用户。判断用户是否存在 若不存在直接返回进入二层拦截器

    3.4把用户转为userDTO对象

    3.5保存在ThreadLocal之中

    3.6刷新token有效期

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //TODO 1获取请求头中token
            String token = request.getHeader("authorization");
            if (StrUtil.isBlank(token)){//如果token为空
               return true;
            }
            //TODO 2 基于token获取redis 中的用户
            Map<Object, Object> entries = stringRedisTemplate.opsForHash()
                    .entries(RedisConstants.LOGIN_USER_KEY + token);
            //TODO 3 判断用户是否存在
            if(entries.isEmpty()){
                return true;
            }
            //TODO 5 将查询到的Hash数据转为UserDto对象
            UserDTO userDTO = BeanUtil.fillBeanWithMap(entries, new UserDTO(), false);
            //TODO 6 存在保存信息到ThreadLocal
            UserHolder.saveUser(userDTO);
            // TODO 7.刷新token有效期
            stringRedisTemplate.
                    expire(RedisConstants.LOGIN_USER_KEY + token,RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);
            return true;
        }

    4.二层拦截器

    4.1.从ThreadLocal里面拿user如果为null直接返回flase拦截

    4.2如果不为null 就返回ture 通行

    //二层拦截
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
          //判断是否需要拦截
            if(UserHolder.getUser()==null){
                response.setStatus(401);
                return false;
            }
            //有用户就放行
            return true;
        }
         @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            //移除用户
            UserHolder.removeUser();
        }
    
    UserHolder代码
    
    public class UserHolder {
        private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();
    ​
        public static void saveUser(UserDTO userId){
            tl.set(userId);
        }
    ​
        public static UserDTO getUser(){
            return tl.get();
        }
    ​
        public static void removeUser(){
            tl.remove();
        }
    }

    更多相关内容
  • 利用公共手机获取短信验证码

    千次阅读 2020-02-06 20:03:55
    互联网时代的到来,让 Email(邮箱)和 Sms(短信验证码)都是应用提供者用来验证来访者身份的主要途径。不知道你们有没有遇到这样的情况:想下载某个论坛上的资源,但是要注册,现在都需要实名手机号码进行验证注册,...

    互联网时代的到来,让 Email(邮箱)和 Sms(短信验证码)都是应用提供者用来验证来访者身份的主要途径。不知道你们有没有遇到这样的情况:想下载某个论坛上的资源,但是要注册,现在都需要实名手机号码进行验证注册,注册后又很尴尬,手机号码泄露了,总有卖保险,卖商铺,卖各种东西的给你打电话,陌生电话不接又难受,万一是客户的电话不接又损失了一笔生意。现在,终于可以不用输入真实手机号码,防止日后被电话骚扰了!
    在这里插入图片描述

    基础简介验证码基本原理:

    1、用户填写自己的手机号码,点击“获取验证码”按钮
    2、网站或者APP按规则生成短信验证码,并将用户的手机号码和验证码内容通过短信验证接口发送到验证码短信平台。
    3、验证码短信平台对经过一系列的判断并通过之后(账户余额、内容是否合规、手机号码是否合规、手机号码所属的运营商),将信息提交到相应运营商的服务器。
    4、运营商将短信内容下发到用户的手机。同理,找回密码、获取优惠券的流程与这个类似。
    1、同系统对接后能够实现全自动发送
    2、可以实现全国范围内的全网(移动、联通、电信用户)发送
    3、发送速度快,能够在10-30秒内响应
    4、到达率能够接近100%
    5、能够实现全天24小时发送
    6、分布式构架,杜绝宕机影响,容错能力强,易扩展
    7、多数据库设计,海量储存验证码发送记录
    8、平台对接多条通道,实现高峰期自动分流
    以下介绍 Kevin整理汇总。有些应用可能不是很稳定,如果无法使用,请更换其他相同性质的服务再次尝试。

    1、来读取

    在这里插入图片描述
    遵纪守法的前提下,保护个人隐私,免于被骚扰。目前提供 10+中国手机号在线读取接收短信息验证码注册码。
    网站地址:https://www.laiduqu.com

    2、Receive SMS

    在这里插入图片描述
    进入之后会给 4 个选择的美国号码,请根据实际情况选择。
    网站地址:https://receive-sms.com

    3、Free Online Phone

    在这里插入图片描述
    这个公司不止一个免费在线手机号码网站,如果这个站不能满足需求,可以去他别的站尝试下。
    网站地址:https://www.freeonlinephone.org

    文章来源自微信公众号,如有侵权请联系删除

    展开全文
  • 3、登录,把手机号码和动态验证码(参数)一起提交服务器,再次发送一个请求 4、【本人测试的系统登录需要带有token值,所以还需要正则提取token,并把token储存到头部管理器(若你们没有的话可以忽略这一步)】ok...

     

    思路:

    手机号码登录需要发送两个请求,第一个请求是获取验证码,第二个请求是登录,把验证码和手机号码作为参数一起提交到服务器,

    1、第一个请求,获取服务器返回的验证码(ps:因为是动态的验证码,所以需要做正则提取)使用参数把验证码保存起来

    2、第二个请求,登录,把手机号码和动态验证码(参数)一起提交服务器

    【本人测试的系统登录需要带有token值,所以还需要正则提取token,并把token储存到头部管理器(若你们没有的话可以忽略这一步)】ok,走起!

    打开jmeter,添加线程组

    线程组--添加--配置原件--http请求默认值(方便以后再次访问别的接口时,不用再次输入服务器信息)

     

    线程组--添加--http取样器,

    线程组--添加--监听器--查看结果树

    先运行一下看看,获取验证码接口有没有通,有没有返回的验证码

    OK,接着下一步,在获取短信验证码接口下添加--后置处理器--JSON提取器

    为了验证,添加的json提取器有没有成功拿到msg:后面的参数(短信验证码),需要添加一个debug sampler 调试取样器

    线程组--添加--取样器--debug sampler

    再次运行看看

    到现在完成了第一个接口请求,也是整块的1/3,欧克,接着下一步发送第二个登录请求

    线程组--添加--取样器--http请求

    再次运行看看,接口有没有通,

     

    完成了2/3,因为本人测的系统必须带有token值,所以还需要在登录接口下做正则提取token。与获取短信验证码下面的方式一致,当然也可以使用正则表达式提取器提取,

    因为这个token值是登录之后,再访问所有的接口时都要用的,所以得存放在头部信息管理器里面

    jmeter运行下一个接口时会自动共享token,

    线程组--配置元件--http信息头部管理器

    再运行看看,Json提取器有没有拿到token值,

     

    到此手机号+短信验证码登录成功, 结束!

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 验证码 <el-form-item label="验证码" prop="code"> <el-row :span="24"> <el-col :span="12"> <el-input v-model="ruleForm.code" auto-complete="off" placeholder="请输入验证码" size=...

    验证码

    <template>
      <div>
        <el-main>
          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="手机号" prop="phone">
              <el-input v-model="ruleForm.phone" placeholder="请输入手机号" size=""
                        maxlength="11"></el-input>
            </el-form-item>
    
            <el-form-item label="验证码" prop="code">
              <el-row :span="24">
                <el-col :span="12">
                  <el-input v-model="ruleForm.code" auto-complete="off" placeholder="请输入验证码" size=""
                            maxlength="4"
                            @keyup.enter.native="submitForm('ruleForm')"></el-input>
                </el-col>
                <el-col :span="12">
                  <div class="login-code">
                    <!--验证码组件-->
                    <el-button @click="getCode()" :class="{'disabled-style':getCodeBtnDisable}"
                               :disabled="getCodeBtnDisable">{{ codeBtnWord }}
                    </el-button>
                  </div>
                </el-col>
              </el-row>
            </el-form-item>
    
            <!--滑动验证组件-->
            <Verify></Verify>
    
            <el-form-item>
              <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
            </el-form-item>
          </el-form>
    
        </el-main>
      </div>
    </template>
    

    用到的vue验证工具类

    export default {
      // 限制只能输入数字(可以输入两位小数点)
      limitInputPointNumber(val) {
        if (val === 0 || val === "0" || val === "" || val === undefined) {
          return "";
        } else {
          let value = null;
          value = val.replace(/[^\d.]/g, ""); // 清除“数字”和“.”以外的字符
          value = value.replace(/\.{2,}/g, "."); // 只保留第一个. 清除多余的
          value = value
            .replace(".", "$#$")
            .replace(/\./g, "")
            .replace("$#$", ".");
          value = value.replace(/^(-)*(\d+)\.(\d\d).*$/, "$1$2.$3"); // 只能输入两个小数
          return value;
        }
      },
    
      handleRouteToArray(route) {
        const matchs = route.path.split('/')
        matchs.shift()
        let newMatch = []
        matchs.map((item, i) => {
          if (matchs[i - 1]) {
            item = newMatch[i - 1] + '/' + item
          }
          newMatch.push(item)
        })
        newMatch = newMatch.map(item => {
          return `/${item}`
        })
        return newMatch
      },
    
      //  密码长度8位以上,须包含大写、小写、数字、特殊符号中的任意3种
      testPassWord: function (str) {
        var rC = {
          lW: '[a-z]',
          uW: '[A-Z]',
          nW: '[0-9]',
          sW: '[\\u0020-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E]'
        }
        function Reg (str, rStr) {
          var reg = new RegExp(rStr)
          if (reg.test(str)) return true
          else return false
        }
        if (str.length < 8) {
          return false
        } else {
          var tR = {
            l: Reg(str, rC.lW),
            u: Reg(str, rC.uW),
            n: Reg(str, rC.nW),
            s: Reg(str, rC.sW)
          }
          if ((tR.l && tR.u && tR.n) || (tR.l && tR.u && tR.s) || (tR.s && tR.u && tR.n) || (tR.s && tR.l && tR.n)) {
            // document.title = "密码符合要求"
            return true
          } else {
            return false
          }
        }
      },
    
      // 密码验证8-30位任意字符
      pwdReg: /^([0-9a-zA-Z]|(?:&)|(?:~)|(?:!)|(?:@)|(?:#)|(?:\$)|(?:%)|(?:\^)|(?:\*)){8,30}$/,
    
      // 电话号码验证
      phoneReg: /^1[3|4|5|6|7|8][0-9]{9}$/,
    
      // 格式化金钱
      formatUSD (val, currency) {
        if (val === '' || val === '--' || val === undefined) {
          return '--'
        }
        // 先判断数据是否有小数点
        let newVal = String(Number(val).toFixed(2))
        // 将科学计数转为正常的字符串显示
        if (newVal.includes('e+')) {
          newVal = Number(newVal).toLocaleString()
          newVal = this.unFormatAmount(newVal)
        }
        let dotIdx = newVal.lastIndexOf('.')
        let dotVal = '.00' // 保留小数点后面的数据
        if (dotIdx >= 0) {
          dotVal = newVal.substr(dotIdx, newVal.length)
          newVal = newVal.slice(0, dotIdx)
        }
    
        let len = newVal.length
        let arr = []
        let lastIndex = null
        while (len > 0) {
          lastIndex = len
          len -= 3
          arr.unshift(newVal.substring(len, lastIndex))
        }
        val = arr.join(',')
    
        if (currency) {
          newVal = `${currency} ${val}${dotVal}`
        } else {
          // newVal = `$ ${val}${dotVal}`
          newVal = `¥ ${val}${dotVal}` // 默认人民币
        }
        return newVal
      },
    
      // 格式化金额数字,不包含小数点,金额符等 输入整数
      formatAmount (val) {
        if (val === '' || val === '--' || val === undefined) {
          return '--'
        }
        if (val === 0 || val === '0') {
          return 0
        }
        // 先判断数据是否有小数点
        let newVal = String(val)
        let dotIdx = newVal.lastIndexOf('.')
        let dotLength = 0
        if (newVal.split('.').length > 1) {
          dotLength = newVal.split('.')[1].length
        }
        let dotVal = '' // 保留小数点后面的数据
        if (dotIdx >= 0) {
          newVal = String(Number(val).toFixed(5))
          dotVal = newVal.substr(dotIdx, dotLength + 1)
          newVal = newVal.slice(0, dotIdx)
        }
        let len = newVal.length
        let arr = []
        let lastIndex = null
        while (len > 0) {
          lastIndex = len
          len -= 3
          arr.unshift(newVal.substring(len, lastIndex))
        }
        val = arr.join(',')
        if (dotVal.length < 2) {
          dotVal = ''
        }
        return val + dotVal
      },
    
      // 判断数据是否为空
      isEmptyVal (val) {
        if (val === undefined || val === '') {
          return '--'
        } else {
          return val
        }
      },
    
        // 格式化年月日   type: 中国显示方式(ch)及拼接的方式
      // 注: 只有在接口传参时才需要中国的显示方式,其它为美式
      formatYMD (now, type='ch') {
        if (!now || now === 'null' || now === '--' || now === undefined) {
          return '--'
        }
        if (Number(now)) {
          now = new Date(now)
        }
        // 兼容IE浏览器 , YY-MM-DD 格式
        if (typeof now === 'string' && now.includes('-')) {
          now = this.NewDate(now)
        }
        if (now) {
          let year = ''
          let month = ''
          let date = ''
          // 这里的8位用于返回如 20180423 这样的格式
          if (String(now).length === 8 && String(now).indexOf('-') === -1 && String(now).indexOf('/') === -1) {
            const getNow = String(now)
            return `${getNow.substring(4, 6)}/${getNow.substring(6, 8)}/${getNow.substring(0, 4)}`
          } else {
            now = new Date(now)
            year = now.getFullYear()
            month = now.getMonth() + 1
            date = now.getDate()
          }
          if (month < 10) {
            month = `0${month}`
          }
          if (date < 10) {
            date = `0${date}`
          }
          if (type === 'ch') {
            return `${year}-${month}-${date}`
          } else if (type) {
            return `${year}${type}${month}${type}${date}`
          } else {
            return `${month}/${date}/${year}`
          }
        } else {
          return ''
        }
      },
    
      // 格式化时间 年,月,日,时,分,秒
      formatDate (now, type) {
        if (!now || now === 'null' || now === '--' || now === undefined) {
          return '--'
        }
        if (now) {
          now = new Date(now)
          let year = now.getFullYear()
          let month = now.getMonth() + 1
          let date = now.getDate()
          let hour = now.getHours()
          let minute = now.getMinutes()
          let second = now.getSeconds()
          if (month < 10) {
            month = `0${month}`
          }
          if (date < 10) {
            date = `0${date}`
          }
          if (hour < 10) {
            hour = `0${hour}`
          }
          if (minute < 10) {
            minute = `0${minute}`
          }
          if (second < 10) {
            second = `0${second}`
          }
          if (type) {
            return `${month}/${date}/${year} ${hour}:${minute}:${second}`
          } else {
            return `${month}-${date}-${year}`
          }
        } else {
          return ''
        }
      },
    }
    

    直接放上完整的这样有助于看

    <template>
      <div>
        <el-main>
          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="手机号" prop="phone">
              <el-input v-model="ruleForm.phone" placeholder="请输入手机号" size=""
                        maxlength="11"></el-input>
            </el-form-item>
    
            <el-form-item label="验证码" prop="code">
              <el-row :span="24">
                <el-col :span="12">
                  <el-input v-model="ruleForm.code" auto-complete="off" placeholder="请输入验证码" size=""
                            maxlength="4"
                            @keyup.enter.native="submitForm('ruleForm')"></el-input>
                </el-col>
                <el-col :span="12">
                  <div class="login-code">
                    <!--验证码组件-->
                    <el-button @click="getCode()" :class="{'disabled-style':getCodeBtnDisable}"
                               :disabled="getCodeBtnDisable">{{ codeBtnWord }}
                    </el-button>
                  </div>
                </el-col>
              </el-row>
            </el-form-item>
    
            <!--滑动验证组件-->
            <Verify></Verify>
    
            <el-form-item>
              <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
            </el-form-item>
          </el-form>
    
        </el-main>
      </div>
    </template>
    
    <script>
    //导入工具类
    import Verify from "@/components/Verify";
    import event from "../utils/event"
    import common from "@/utils/common";
    
    let params;
    export default {
      name: "LoginIphone",
      components: {Verify},
      data() {
        //使用正则表达式验证手机号
        const checkPhone = (rule, value, callback) => {
          if (!value) {
            return callback(new Error('手机号不能为空'));
          } else {
            //获取工具类中的手机号正则表达式
            const reg = common.phoneReg
            // console.log(reg.test(value));
            if (reg.test(value)) {
              callback();
            } else {
              //如果验证输入错误就清空
              this.ruleForm.phone = ''
              return callback(new Error('请输入正确的手机号'));
            }
          }
        };
    
        return {
          ruleForm: {
            phone: '',
            code: '',
          },
    
          codeBtnWord: '获取验证码', // 获取验证码按钮文字
          // waitTime: 61, // 获取验证码按钮失效时间
          waitTime: 2, // 获取验证码按钮失效时间
          // 校验
          rules: {
            phone: [
              {validator: checkPhone, trigger: 'blur'}
            ],
            code: [
              {required: true, message: '请输入验证密码', trigger: 'blur'}
            ]
          }
        };
      },
      //计算属性computed
      computed: {
        // 控制获取验证码按钮是否可点击
        getCodeBtnDisable: {
          //设置按钮61s
          // get() {
          //   if (this.waitTime === 61) {
          //     if (this.ruleForm.phone) {
          //       return false
          //     }
          //     return true
          //   }
          //   return true
          // }
          get() {
            if (this.waitTime === 2) {
              if (this.ruleForm.phone) {
                return false
              }
              return true
            }
            return true
          },
          // 注意:因为计算属性本身没有set方法,不支持在方法中进行修改,而下面我要进行这个操作,所以需要手动添加
          set() {
          }
        },
    
      }, methods: {
    
        getCode() {
          const _this = this
          params = {}
          params.phone = this.ruleForm.phone
          // 调用获取短信验证码接口
          _this.$axios.post('/sendMessage', params).then(res => {
            console.log("--------查看后台响应的值-----", res)
            //把所有的数据存在
            const mydata = res.data.data
            console.log("我在短信接口这利-->", mydata)
    
            //保存验证码
            params.yz = mydata.vCode
    
            console.log("我是查看验证码-------" + mydata.vCode)
            console.log("我是查看调用的次数-------" + mydata.count)
    
            if (res.data.code === 200) {
              this.$message({
                message: '验证码已发送,请稍候...',
                type: 'success',
                center: true
              })
            }
            if (res.data.data.count >= 5) {
              //调用滑块验证的组件
              event.$emit("VERIFY")
            }
    
          })
    
          // 因为下面用到了定时器,需要保存this指向
          let that = this
          that.waitTime--
          that.getCodeBtnDisable = true
          this.codeBtnWord = `${this.waitTime}s 后重新获取`
          let timer = setInterval(function () {
            if (that.waitTime > 1) {
              that.waitTime--
              that.codeBtnWord = `${that.waitTime}s 后重新获取`
            } else {
              clearInterval(timer)
              that.codeBtnWord = '获取验证码'
              that.getCodeBtnDisable = false
              // that.waitTime = 61
              that.waitTime = 2
            }
          }, 1000)
        },
        submitForm(formName) {
          const _this = this
          //判断输入的验证码是否为空
          if (this.ruleForm.code != null) {
            this.$refs[formName].validate((valid) => {
              if (valid) {
    
                _this.$axios.post("/iosLogin", {
                  "phone": this.ruleForm.phone,
                  "Verification": this.ruleForm.code
                }).then(res => {
    
                  console.log(res.data)
                })
    
    
                // console.log("我是提交里面的:", par)
                //
                // const jwt = par.headers['authorization']
                // console.log("我是token->", jwt)
                // const userInfo = par.data.data
                // console.log("查看用户信息=", userInfo)
                //
                // // 把数据共享出去
                // _this.$store.commit("SET_TOKEN", jwt)
                // _this.$store.commit("SET_USERINFO", userInfo)
                //
                // // 获取
                // console.log("我是获取的_this.$store.getters.getUser")
                // console.log(_this.$store.getters.getUser)
    
                // _this.$router.push("/blogs")
    
              } else {
                console.log('error submit!!');
                return false;
              }
            });
          } else {
            this.$message({
              showClose: true,
              message: '请输入错误',
              type: 'error'
            });
          }
        }
    
      }
    
    }
    </script>
    <style scoped>
    .el-button.disabled-style {
      background-color: #EEEEEE;
      color: #CCCCCC;
    }
    
    .demo-ruleForm {
      max-width: 500px;
      margin: 0 auto;
    }
    </style>
    
    
    展开全文
  • 一片云验证码平台,提供大量共享手机号,平台集各类网站用户账号注册、验证、解封等手机验证码,用户在一片云平台可以自由实现手机验证码的在线收发,操作简单方便。淘宝、
  • 验证时使用用户输入的验证码和一段时间内生成的验证码集合对比,如果在此集合,则证明验证码有效。摆脱使用redis等方式存储和对比验证码。 使用 class Totp { private $salt = 'salt'; // 盐 private $...
  • 手机快速登录功能,就是通过...为获取验证码按钮绑定事件,并在事件对应的处理函数中校验手机号,如果手机号输入 正确则显示30秒倒计时效果并发送ajax请求,发送短信验证码 登录页面: <div class="input-row">
  • 隐私问题不想用自己手机... 这些网站的手机号码所有人共享,也会看到他人的短信内容。用于注册帐户通过验证,或者想收一则短信又不希望告诉对方真实号码还是很好使的。 本文要介绍的3个在线收手机短信验证码的免...
  • 2. 有前端的视图我们可以看到, 传入的参数为手机号验证码,我们用BO对其进行统一的封装,同时使用valid 对参数进行统一的判空 ; 接口就是我们后端要编写的代码内容 //@data 我们不使用lombok注解,因为可能在某一些...
  • 为了实现在手机注册和登录时获取手机验证码,我使用了阿里的短信服务,下面就来介绍一下具体如何实现。将介绍代码层面如何使用的,去阿里开通该服务,以及如何获得你的accessKeyId和accessKeySecret等。 一、在...
  • @RequestMapping("/haha/getnum") public void getNum(@RequestParam("phoneNumber") String phoneNumber){ logger.info("手机号为:"+phoneNumber); Jedis jedis = jedisUtil.getJedis(); String countKey = phone...
  • 一,session共享 首先第一个要解决的就是sesison共享的问题,如下图。 通常有两种解决方案,第1种是配置nginx的负载集群策略为ip_hash,第2种是将session存储到其它地方,一般推荐放到redis中。 第1种方案适合于...
  • 手机验证码在很多网站都会用到,比如说注册登录以及修改信息的时候,如果不输入正规的手机验证码就不能进行下一步操作。那么为什么网站要使用手机验证码呢,作为企业有没有必要给网站或者是APP加上手机验证码功能呢...
  • 这里我使用的是阿里云的短信服务,首先需要登录阿里云官方网站,找到并开通短信服务,然后需要申请短信签名和模版。 1. 由于页面展示东西太多可以搜索 “短信服务” 关键词 (如果是登录状态就是如下的图) ...
  • 对于内网安全建设,存在的很多通用并且很棘手的问题,比如弱密码,比如账号泄露,账号共享,默认账号,员工一般认为在内网我就是安全的,所以放松警惕,当出现安全问题的时候, 又说这不是自己的行为,这就给安全造成...
  • [小黄书后台]手机短信验证码

    千次阅读 2019-06-22 18:38:25
    今天我们会实现手机验证码的功能。 我们现在到处都会碰到手机验证码的验证方式,比如在注册的时候,通过输入手机号码,获取一个验证码,然后输入完成注册。 1. 螺丝帽 vs 云片 一开始的时候,我们往往疲于短信服务...
  • Java实现短信验证码

    千次阅读 2022-03-04 15:29:53
    登录注册页面需要确保用户同一个手机号只关联一个账号确保非人为操作,避免系统用户信息紊乱增加系统安全性 代码实现 同事提供了WebService接口,很好,之前没调过,又增加了困难。 这边用的阿里云的短信服务,废话...
  • 4、注册前需要判断当前填写的手机号和用户名是否存在,如果存在,则不进行注册。 5、以上步骤通过后,开始准备需要保存的数据,用户的登录密码使用盐值加密(防止使用MD5加密被暴力破解),最后将数据保存进数据库中...
  • 一、从一开始的通过将验证码存入session 我们当时从session中取出验证码,然后完成后面相关的登录认证等操作。 但是这样的方式很有可能造成比方因为tomcat集群导致的session共享问题,因为session是存储在服务端的...
  • 应用场景:登录验证,注册账号,密码找回,绑定手机号等功能 1. 本接口采用的是聚合数据接口:https://www.juhe.cn/docs/api/id/54 2. 首先,注册账号申请快递单号接口:获取申请的key 3. 短信模板申请 3.1. 因为...
  • 秒杀系统——注册验证码跨域Session不共享问题 一、原因 这里注册验证码跨域Session不共享问题的原因是因为前后端分离, 二、解决方法
  • 目录1....这种方式相对于用户名密码登录方式,用户不需要记忆自己的密码,只需要通过输入手机号并获取验证码就可以完成登录,是目前比较流行的登录方式。 2. 手机快速登录 2.1 页面调整 登录页面为/page
  • 一次性验证码

    千次阅读 2016-04-11 15:27:04
    了解在服务器端,不同的servlet可以通过session获取浏览器缓存(cookie)从而共享数据(主要是session.setAttribute()和session.getAttribute()函数) 2.在HTML中,如何调用不同servlet的数据 3.对图形函数的...
  • Java开发完整的短信验证码功能

    千次阅读 多人点赞 2021-10-11 22:45:00
    现代互联网项目中,很多场景下都需要使用一种叫做验证码的技术,常用的有图片验证码,滑块验证码,短信验证码等,本文章描述的就是短信验证码的一个使用教程,从0开始完成一个验证码功能的开发。 闲扯 是不是看着...
  • 短信验证码接口示例,如何接入短信API接口实现短信自动发送功能; 网站如何实现自动发送短信验证码的功能,短信验证码技术文档需要哪些参数,网站点击触发验证码的功能实现的方法,通过调用API接口的方式实现短信...
  • 短信验证码有什么限制?

    千次阅读 2020-09-21 17:13:38
    随着互联网的共享,人们对于个人信息的安全也有了一定的认识与了解,短信验证码就是对个人信息的一个重要的屏障。一般而言为了防止有些人无聊或是恶意的重复获取短信验证码,给服务器带来过重压力,而不能正常运行,...
  • 在说Android中的短信验证码这个知识点前,我们首先来了解下聚合数据 聚合数据介绍 聚合数据是一家国内最大的基础数据API提供商,专业从事互联网数据服务。免费提供从天气查询、空气质量、地图坐标到金融基金、电商...
  • 每个Android设备都有唯一的国际移动设备识别码(IMEI)。 与运营商或设备制造商联系时,可能需要此号码。 找到这两种方法有两种。...IMEI码的长度为14-16位,大多数由14位数字和最后一位验证码组成。运营商和制...
  • 一个基于springboot的二级共享单车的后台系统,包括手机号码注册,登陆,定位,骑行轨迹和消息推送等功能 技术栈: SpringBoot SpringMVC Mybatis(基础框架)Mysql springSecurity(权限验证和请求拦截) AES...
  • 输入所要查询的手机号码,并输入验证码↓↓↓   点击“查询”即可立即查询到自己的手机号码是否被标记。 该网站目前除了提供号码标记查询服务之外,还提供号码误标记清除服务↓↓↓     查询说明...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,432
精华内容 1,772
关键字:

共享手机号验证码

友情链接: Varsha.rar