基于nodejs、mongodb之外卖平台后端接口开发文档(三)

  1. 下面开发登录接口,登录接口分为两种,一种是账号密码登录,一种是手机+验证码登录,因为要用到验证码,这里要封装一下生成验证码和校验验证码的方法,在utils文件夹下新建sms.js
    ps:这里用到的是阿里云的验证码,阿里云的短信服务应该需要公司身份才能申请,所以有需要的同学看,没办法申请的 略过这个 手机+验证码登录的接口即可
    ps:需要用到两个插件 @alicloud/pop-core 、 lodash
cnpm install @alicloud/pop-core  lodash  --save
/**
 * sms.send(手机号) 发送短信验证码
 * sms.verify(手机号,验证码) 校验验证码是否正确
 **/

const Core = require('@alicloud/pop-core');
const _ = require('lodash');

// 阿里云控制台 - 短信服务 - 国内消息
const SignName = "xxxx"; //换你自己的签名
const TemplateCode = "xxxxx"; //换你自己的模版code

// https://usercenter.console.aliyun.com/
const accessKeyId = "xxxxxx"; // 换你自己的key
const accessKeySecret = "xxxxxxx"; //换你自己的密钥

var client = new Core({
    accessKeyId,
    accessKeySecret,
    endpoint: 'https://dysmsapi.aliyuncs.com',
    apiVersion: '2017-05-25'
});

// 保存手机号和验证码的对应关系
// phone_code_list = {'18855551234':['1024']}
var phone_code_list = {};

exports.send = function(phone) {
    function randomCode(length) {
        var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        var result = "";
        for (var i = 0; i < length; i++) {
            var index = Math.ceil(Math.random() * 9);
            result += chars[index];
        }
        return result;
    }
    // 生成验证码
    // var code = "" + _.random(9) + _.random(9) + _.random(9) + _.random(9);
    var code = randomCode(6);
    console.log(code);

    return new Promise((resolve, reject) => {
        try {
            client.request('SendSms', {
                RegionId: "cn-hangzhou",
                PhoneNumbers: phone,
                SignName,
                TemplateCode,
                TemplateParam: "{code:" + code + "}"
            }, {
                method: 'POST'
            }).then((result) => {
                if (result.Message && result.Message == "OK" && result.Code && result.Code == "OK") { // 短信发送成功
                    // 保存验证码
                    if (phone_code_list[phone]) {
                        phone_code_list[phone].push(code);
                    } else {
                        phone_code_list[phone] = [code];

                    }
                    // 三分钟后删除验证码
                    setTimeout(() => {
                        _.pull(phone_code_list[phone], code);
                        if (phone_code_list[phone] && phone_code_list[phone].length == 0) {
                            delete phone_code_list[phone];
                        }
                    }, 3 * 60 * 1000)
                    resolve(result)
                } else {
                    reject(result)
                }
            }, (ex) => {
                reject(ex)
            })
        } catch (error) {
            reject(error)
        }
    })
}

exports.verify = function(phone, code) {
    if (phone_code_list[phone] != undefined) {
        return (phone_code_list[phone].indexOf(code) > -1)
    } else {
        return false
    }

}
  1. 在user.js内引入 sms.js
//引入token.js  
var vertoken = require('../utils/token')
// 引入sms.js
const sms = require("../utils/sms")
  1. 开始编写用户名+密码的登录方式,先在utils文件夹下新建一个filter.js,把非空检验过滤器简单封装下
//用户名+密码登录接口的过滤器
let loginFilter = (req, res, next) => {
    if (req.body.loginame && req.body.password) {
        next()
    } else {
        res.json({
            code: -1,
            msg: "用户名或密码不能为空"
        })
    }
}

module.exports = {
    loginFilter,
}
  1. 在user.js内引入这个过滤器
// 引入sms.js
const sms = require("../utils/sms")
//引入过滤filter.js
const filter = require("../utils/filter")
  1. 用户名+密码的登录接口如下:
//用户名+密码登录接口
router.post('/login', filter.loginFilter, (req, res) => {
    const loginame = req.body.loginame;
    const password = md5(req.body.password);
    User.find({ loginame }, (err, docs) => {
        if (docs.length == 0) {
            res.json({ code: -1, message: '该用户不存在' })
        } else if (docs[0].password !== password) {
            res.json({ code: -1, message: '用户名或密码错误' })
        } else {
            vertoken.setToken(docs[0]._id, docs[0].loginame, docs[0].identity).then(token => {
                res.json({ code: 200, data: token, message: '登录成功' })
            })
        }
    })
})

ps:注册接口实际上也可以用loginFilter过滤器,可以在注册接口的后面加上filter.loginFilter

router.post('/register', filter.loginFilter, (req, res) =>{ })
  1. 在写手机号+验证码登录接口之前,我们先来实现一下发送验证码的接口
//发送验证码
router.post('/sendSms', filter.sendSmsFilter, (req, res) => {
    const phone = req.body.phone
    sms.send(phone).then(result => {
        res.json({
            code: 200,
            message: "短信发送成功!",
        })
    }).catch(err => {
        res.json({
            code: -1,
            message: err
        })
    })
})
  1. 现在我们再来开发手机号+验证码的登录接口 记得配置非空校验过滤器
//手机号+验证码登录接口的过滤器
let loginSmsFilter = (req, res, next) => {
    if (req.body.phone && req.body.code) {
        next()
    } else {
        res.json({
            code: -1,
            msg: "手机号码或验证码不能为空"
        })
    }
}

ps:我们要清楚,我们写的这个接口,用户手机号如果没有注册过,我们默认给他注册,走注册流程,即登录即注册!!否则就直接登录成功,返回token

router.post('/login/sms', filter.loginSmsFilter, (req, res) => {
    const phone = req.body.phone;
    const code = req.body.code;
    var isCodeRight = sms.verify(phone, code);
    if (isCodeRight) {
        res.json({ code: -1, message: "手机号或验证码错误" })
    } else {
        User.find({ phone }, (err, docs) => {
            //该用户不存在,走默认注册流程 loginame 设置成phone
            if (docs.length == 0) {
                const newUser = new User({
                    loginame: req.body.phone,
                    phone: req.body.phone,
                });
                newUser.save((err, result) => {
                    if (err) {
                        res.json({ code: -1, message: err })
                    } else {
                        vertoken.setToken(result._id, result.loginame, result.identity).then((token) => {
                            res.json({
                                code: 200,
                                token: token,
                                message: '登录成功'
                            })
                        })
                    }
                })
            } else {
                //存在直接返回token
                vertoken.setToken(docs[0]._id, docs[0].loginame, docs[0].identity).then((token) => {
                    res.json({
                        code: 200,
                        token: token,
                        message: '登录成功'
                    })
                })
            }
        })
    }
})

  1. 再来开发一个获取用户信息的接口,前端登录后要用到。
//获取用户信息
router.get('/getInfo', (req, res) => {
    vertoken.getToken(req.headers.token).then((data) => {
        res.json({ code: 200, data, message: "请求成功", })
    }).catch((error) => {
        res.json({
            code: 401,
            message: "token失效了"
        })
    })
})

前台登录注册接口开发完毕!end
接下一章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容