IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 使用egg.js实现手机、验证码注册 -> 正文阅读

[JavaScript知识库]使用egg.js实现手机、验证码注册

手机号注册、验证码校验

app/contrpoller/pass.js

'use strict';
const Controller = require('egg').Controller;
class PassController extends Controller {
 //登录
  async login() {
    await this.ctx.render('pass/login.html');
  }
  async getCode(){
    const { ctx,service } = this;
    const captcha=await service.tools.verify(); /* 获取服务里面返回的生成的验证码信息 */
    this.ctx.session.identify_code=captcha.text;  /* 验证码上面的信息,文字内容存放到session里面 */
    ctx.response.type = 'image/svg+xml';  /* 返回的生成的验证码的格式 */
    ctx.body=captcha.data;  /* 给页面返回一张图片 */
  }
   //注册第一步 输入手机号
  async registerStep1() {
    await this.ctx.render('pass/register_step1.html');
  }
  //注册第二步  验证码验证码是否正确
  async registerStep2() {
    var sign=this.ctx.request.query.sign;
    var identify_code=this.ctx.request.query.identify_code;
    var add_day=await this.service.tools.getDay();         //年月日
    var userTempResult=await this.ctx.model.User.UserTemp.find({"sign":sign,add_day:add_day});
    if(userTempResult.length==0){
      this.ctx.redirect('/register/registerStep1');
    }else{
      await this.ctx.render('pass/register_step2.html',{
        sign:sign,
        phone:userTempResult[0].phone,
        identify_code:identify_code
      });
    }
  }
  //注册第三步  输入密码
  async registerStep3() {
    var sign = this.ctx.request.query.sign;
    var phone_code = this.ctx.request.query.phone_code;
    var msg = this.ctx.request.query.msg || '';
    var add_day = await this.service.tools.getDay();         //年月日
    var userTempResult = await this.ctx.model.User.UserTemp.find({ "sign": sign, add_day: add_day });
    if (userTempResult.length == 0) {
      this.ctx.redirect('/register/registerStep1');
    } else {
      await this.ctx.render('pass/register_step3.html', {
        sign: sign,
        phone_code: phone_code,
        msg: msg
      });
    }
  }

    //完成注册  post
  async doRegister() {
    this.ctx.body='完成注册';
  }

  //发送短信验证码
  async sendCode(){
    var phone=this.ctx.request.query.phone;
    var identify_code=this.ctx.request.query.identify_code;  //用户输入的验证码
    if(identify_code.toLowerCase()!=this.ctx.session.identify_code.toLowerCase()){
        this.ctx.body={
          success:false,
          msg:'输入的图形验证码不正确'
        }
    }else{
        //判断手机格式是否合法
        var reg =/^[\d]{11}$/;
        if(!reg.test(phone)){
          this.ctx.body={
            success:false,
            msg:'手机号不合法'
          }
        }else{
          var add_day=await this.service.tools.getDay();         //年月日
          var add_time=await this.service.tools.getTime();
          var sign=await this.service.tools.md5(phone+add_day);  //签名
          var ip=this.ctx.request.ip.replace(/::ffff:/, '');     //获取客户端ip
          var phone_code=await this.service.tools.getRandomNum();  //发送短信的随机码
          var userTempResult=await this.ctx.model.User.UserTemp.find({"sign":sign,add_day:add_day});
          //1个ip 一天只能发10个手机号
          var ipCount=await this.ctx.model.User.UserTemp.find({"ip":ip,add_day:add_day}).count();
          if(userTempResult.length>0){
              if(userTempResult[0].send_count<6 && ipCount<10){                     //执行发送
                    var send_count=userTempResult[0].send_count+1;
                    await this.ctx.model.User.UserTemp.updateOne({"_id":userTempResult[0]._id},{"send_count":send_count,'add_time':add_time});
                    this.ctx.session.phone_code=phone_code;
                    //发送短信
                    this.service.sendmsg.send(phone,phone_code);
                    console.log('---------------------------------');
                    console.log(phone_code,ipCount);
                    this.ctx.body={
                      success:true,
                      msg:'短信发送成功',
                      sign:sign,
                    }
              }else{
                    this.ctx.body={"success":false,msg:'当前手机号码发送次数达到上限,明天重试'};
              }
          }else{
              var userTmep=new this.ctx.model.User.UserTemp({
                  phone,
                  add_day,
                  sign,
                  ip,
                  send_count:1
              });
              userTmep.save();
              this.ctx.session.phone_code=phone_code;
              //发送短信
              this.service.sendmsg.send(phone,phone_code);
              this.ctx.body={
                success:true,
                msg:'短信发送成功',
                sign:sign,
              }
          }
        }
    }
  }


  //验证验证码
  async validatePhoneCode(){
    var sign=this.ctx.request.query.sign;
    var phone_code=this.ctx.request.query.phone_code;
    var add_day=await this.service.tools.getDay();         //年月日
    if(this.ctx.session.phone_code!=phone_code){
      this.ctx.body={
        success:false,
        msg:'您输入的手机验证码错误'
      }
    }else{
      var userTempResult=await this.ctx.model.User.UserTemp.find({"sign":sign,add_day:add_day});
      if(userTempResult.length<=0){
        this.ctx.body={
          success:false,
          msg:'参数错误'
        }
      }else{
        //判断验证码是否超时
        var nowTime=await this.service.tools.getTime();
        if((userTempResult[0].add_time-nowTime)/1000/60>30){
          this.ctx.body={
            success:false,
            msg:'验证码已经过期'
          }
        }else{
          //用户表有没有当前这个手机号        手机号有没有注册
          var userResult=await this.ctx.model.User.User.find({"phone":userTempResult[0].phone});
          if(userResult.length>0){
            this.ctx.body={
              success:false,
              msg:'此用户已经存在'
            }
          }else{
            this.ctx.body={
              success:true,
              msg:'验证码输入正确',
              sign:sign
            }
          }
        }
      }
    }
  }


  //完成注册  post
  async doRegister() {
    var sign=this.ctx.request.body.sign;
    var phone_code=this.ctx.request.body.phone_code;
    var add_day=await this.service.tools.getDay();         //年月日
    var password=this.ctx.request.body.password;
    var rpassword=this.ctx.request.body.rpassword;
    var ip=this.ctx.request.ip.replace(/::ffff:/, '') ;
    if(this.ctx.session.phone_code!=phone_code){
      //非法操作
      this.ctx.redirect('/pass/registerStep1');
    }
    var userTempResult=await this.ctx.model.User.UserTemp.find({"sign":sign,add_day:add_day});
    if(userTempResult.length==0){
      //非法操作
      this.ctx.redirect('/pass/registerStep1');
    }else{
      //传入参数正确 执行增加操作
      if(password.length<6 || password!=rpassword){
        var msg='密码不能小于6位并且密码和确认密码必须一致';
        this.ctx.redirect('/register/registerStep3?sign='+sign+'&phone_code='+phone_code+'&msg='+msg);
      }else{
          var userModel=new this.ctx.model.User.User({
          phone:userTempResult[0].phone,
          password:await this.service.tools.md5(password),
          last_ip:ip
        });
        //保存用户
        var userReuslt=await userModel.save();
        if(userReuslt){
          //跳转到登入页面
          this.ctx.redirect('/login');
        }
        // if(userReuslt){
        //   //获取用户信息
        //   var userinfo=await this.ctx.model.User.User.find({"phone":userTempResult[0].phone},'_id phone last_ip add_time email status');
        //   //用户注册成功以后默认登录
        //   //cookies 安全      加密
        //   this.service.cookies.set('userinfo',userinfo[0]);
        //   this.ctx.redirect('/');
        // }
      }
    }
  }
}
module.exports = PassController;

mode/user.js

module.exports = app => {
    const mongoose = app.mongoose;
    const Schema = mongoose.Schema;
    var d=new Date();
    const User = new Schema({
      /*
        ip:ip,
              password:password,
              phone:phone,
              add_time:add_time,
              last_ip:last_ip,
              status:status
      */
      password:{type:String },
      phone: {type:Number },
      last_ip:{type:String },
      add_time: {
        type:Number,
        default: d.getTime()
      },
      email:{type:String },
      status: {
        type:Number,
        default: 1
      }
    });
    return mongoose.model('User', User,'user');
};

router.js 路由配置

module.exports = app => {
    const { router, controller } = app;

    //普通用户登入
    router.get('/user/verify', controller.admin.base.verify);
    //用户注册登录
    router.get('/login',controller.default.pass.login);
    router.get('/register/registerStep1', controller.default.pass.registerStep1);
    router.get('/register/registerStep2', controller.default.pass.registerStep2);
    router.get('/register/registerStep3', controller.default.pass.registerStep3);
    //用户点击注册
    router.get('/pass/sendCode', controller.default.pass.sendCode);
    //注册前台验证码
    router.get('/verify', controller.default.pass.getCode);
    //注册验证手机短信码
    router.get('/pass/validatePhoneCode', controller.default.pass.validatePhoneCode);
    //注册最后一步,输入账号和密码
    router.post('/pass/doRegister', controller.default.pass.doRegister);
};

service.js

获取验证码

'use strict';
//引入node.js  生成svg图形验证码模块
const svgCaptcha = require('svg-captcha');
const Service = require('egg').Service;
const md5 = require('md5');
const path=require('path');
const sd = require('silly-datetime');
const mkdirp = require('mz-modules/mkdirp');
const Jimp = require("jimp");  //生成缩略图的模块
class ToolsService extends Service {
  async verify() {  /* 生成验证码 */
    const captcha = svgCaptcha.create(
      {
        size:4,     //验证码图片里面的一些信息
        fontSize: 50,
        width: 100,
        height:40,
        background: "#cc9966"
      });
    return  captcha;
  }
  /*生成随机的4位数字*/
  async getRandomNum(){
      let num='';
      for(var i=0;i<4;i++){
        num+=Math.floor(Math.random()*10)
      }
      return num;
    }
  /*生成当年当月当天的数字*/
  async getDay(){
    const day=sd.format(new Date(), 'YYYYMMDD');
    return day;
  }
  /* 生成当前时间*/
  async getTime(){
     var date=new Date();
     return date.getTime();
  }
  async md5(string){   /* 封装一个md5加密*/
        return  md5(string);
  }
  async getFocusAddPath(filename){
      /*
          1: 获取传递过来的图片的名字, 获取当前日期 silly-datetime模块
          2: 根据当前的日期,设置对应的文件夹,如果存在就不设置,不存在就设置 mz-modules模块
      */
     const day=sd.format(new Date(), 'YYYYMMDD');
     let dir=path.join(this.config.uploadDir,day);
     await mkdirp(dir);
     const date=new Date();
     let d=await date.getTime();   /*毫秒数*/
     /*图片保存的路径*/
     let uploadDir=path.join(dir,d+path.extname(filename));
     /*app\public\admin\upload\20190614\1560520826971.png */
    return {
      uploadDir:uploadDir,
      /* 保存到数据库的地址 */
      saveDir:uploadDir.slice(3).replace(/\\/g,'/')
    }
  }
  //生成缩略图的公共方法
  async jimpImg(target){
    //上传图片成功以后生成缩略图
    Jimp.read(target, (err, lenna) => {
      if (err) throw err;
      lenna.resize(200, 200) // resize
        .quality(90) // set JPEG quality
        .write(target+'_200*200'+path.extname(target)); // save
      lenna.resize(400, 400) // resize
        .quality(90) // set JPEG quality
        .write(target+'_400*400'+path.extname(target)); // save
    });
  }

}
module.exports = ToolsService;


sendmsg.js

发送短信验证码

(需要上云片网购买短信服务)

'use strict';
const Service = require('egg').Service;
var https = require('https');
var qs = require('querystring');
class SendmsgService extends Service {
  async send(mobile,code) {
    //apikey自己到云片网上面去买。
    var apikey = '092******************eec';
    // 修改为您要发送的手机号码,多个号码用逗号隔开
    var mobile = mobile;
    // 修改为您要发送的短信内容
    var text = '【java学习网】您的验证码是'+code;
    // 智能匹配模板发送https地址
    var sms_host = 'sms.yunpian.com';
    var send_sms_uri = '/v2/sms/single_send.json';
    // 指定模板发送接口https地址
    send_sms(send_sms_uri,apikey,mobile,text);
    function send_sms(uri,apikey,mobile,text){
        var post_data = {
        'apikey': apikey,
        'mobile':mobile,
        'text':text,
        };//这是需要提交的数据
        var content = qs.stringify(post_data);
        post(uri,content,sms_host);
    }
    function post(uri,content,host){
        var options = {
            hostname: host,
            port: 443,
            path: uri,
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            }
        };
        var req = https.request(options, function (res) {
            // console.log('STATUS: ' + res.statusCode);
            // console.log('HEADERS: ' + JSON.stringify(res.headers));
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                 console.log('BODY: ' + chunk);     //如果错误  自己把它写入一个日志
            });
        });
        //console.log(content);
        req.write(content);
        req.end();
    }

  }
}
module.exports = SendmsgService;

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 12:53:24  更:2022-03-06 12:56:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:12:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码