上一篇:Node.js之Express(二) web登录服务:开发环境搭建

前提:
和朋友ooomyself同学联手搞了一个小游戏项目,需要登录验证!用web登录验证由ooomyself同学提出制作,本人学习(嘿嘿)!
需求:
需要web服务进行注册登录验证。
大致流程:
注册账户(保存到数据库)->登录(数据库查询验证)->验证通过

代码实现

前面开发环境已经配置完成,具体这里实现分三个重要部分:
a.路由设置:
b.数据库链接:
c.前后端交互调试:

用webstorm打开创建的webserver项目,进行相应代码填写。

1.路由设置:
打开routes文件,里面的文件我们不用,为了简洁我这里删掉默认的两个路由文件,及相应引用。
这里新建了一个路由管理类route_controller.js代码如下:

let loginRouter = require('./route_login');

module.exports = function (app) {
    app.use('/', loginRouter);

    //在这里新添加路由模块...
};

关于里面route_login文件,下面会给出,先把这个路由管理类挂到app.js
代码如下:

//删掉原有引入index.js, users.js引入,添加引入
let routeCtrl = require('./routes/route_controller');
......
var app = express();
//设置允许跨域访问该服务.
app.all('*', function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    //Access-Control-Allow-Headers ,可根据浏览器的F12查看,把对应的粘贴在这里就行
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    res.header('Access-Control-Allow-Methods', '*');
    res.header('Content-Type', 'application/json;charset=utf-8');
    next();
});

// 删掉原有index,users调用,添加调用
routeCtrl(app);

接着我们在routes新建rout_login.js文件,填写代码如下:

/*
功能:登录路由
author:yang
date:2019/2/19
*/
let express = require('express');
let router = express.Router();
let util = require('../util/util');
let mgLoginCtrl = require('../models/login/mongo_login');

/* Get users listing. */
router.get('/doReg', function (req, res, next) {
    let arg = req.body;
    let {user, pwd} = arg;
    if (!user || !pwd) {
        util.errResSend(res, '缺少参数');
    } else {
        mgLoginCtrl.regUser(user, pwd, res);
    }
});

router.get('/doLogin', function (req, res, next) {
    let arg = req.body,
        user = arg.user,
        pwd = arg.pwd;
    if (!user || !pwd) {
        util.errResSend(res, '缺少参数!');
    } else {
        mgLoginCtrl.loginUser(user, pwd, res);
    }
});

/* Post users listing*/
router.post('/doReg', function (req, res, next) {
    let arg = req.body;
    let {user, pwd} = arg;
    if (!user || !pwd) {
        util.errResSend(res, '缺少参数');
    } else {
        mgLoginCtrl.regUser(user, pwd, res);
    }
});

router.post('/doLogin', function (req, res, next) {
    let arg = req.body,
        user = arg.user,
        pwd = arg.pwd;
    if (!user || !pwd) {
        util.errResSend(res, '缺少参数!');
    } else {
        mgLoginCtrl.loginUser(user, pwd, res);
    }
});

module.exports = router;

到这里路由模块设置完成,细心的小伙伴会发现,route_login文件中引用了好几个未知文件,不要着急,下面我们慢慢补上。
2.数据库链接
webserver文件目录下新建models文件目录:
mkdir data_basecd data_base data_base目录下,新建mongo_controller.js文件,填写代码如下:

/*
功能:mongo管理类
author:yang
date:2019/2/19
*/
let loginDefine = require('../models/login/login_define');
let mg_ctrl = require('mongoose');

const DB_URL = 'mongodb://localhost/' + loginDefine.MG_DB_NAME;
mg_ctrl.connect(DB_URL, {useNewUrlParser: true});

let db = mg_ctrl.connection;
db.on('error', console.error.bind(console, 'connection error:'));

db.on('connected', function () {
    console.log('Mongoose connection open to' + DB_URL);
});

db.on('disconnected', function () {
    console.log('Mongoose connection disconnected');
});

db.once('open', function () {
    console.log("we're connected!");
});

module.exports = mg_ctrl;

webserver文件目录下新建models文件目录:
mkdir modelscd models 新建login模块目录
mkdir logincd login 新建mongo_login.js文件,填写代码如下:

/*
功能:登录数据管理
author:yang
date:2019/2/19
*/
let loginDefine = require('./login_define');

const DB_LOGIN_TABLE_NAME = loginDefine.DB_LOGIN_TABLE_NAME;
const BASE_ID = loginDefine.INIT_ID;

let mgCtrl = require('../../data_base/mongo_controller');
let util = require('../../util/util');

let schema = mgCtrl.Schema;
let loginMsg = new schema({
    id: Number,
    user: String,
    pwd: String,
});

let loginModel = mgCtrl.model(DB_LOGIN_TABLE_NAME, loginMsg);

let m = {}

m.newUser = function (user, pwd, id, res) {
    let user_model = new loginModel({
        user: user,
        pwd: pwd,
        id: id,
    });
    console.log('user_model...' + user_model);
    user_model.save(function (err) {
        if (err) {
            res.send(util.getResJson(502, '出错了!'));
        } else {
            res.send(util.getResJson(200, '添加成功'));
        }
    })
}

m.findOne = function (user, res, callback) {
    loginModel.findOne({user: user}, function (err, doc) {
        if (err) {
            util.errResSend(res, err.message);
        } else {
            if (doc) {
                return res.send(util.getResJson(501, "用户已存在!"))
            } else {
                return callback();
            }
        }
    })
}

m.regUser = function (user, pwd, res) {
    let self = this;
    this.findOne(user, res, function (err, doc) {
        loginModel.countDocuments({}, function (err, doc) {
            if (err) {
                util.errResSend(res, err.message);
            } else {
                console.log(BASE_ID, doc)
                let id = BASE_ID + doc;
                self.newUser(user, pwd, id, res)
            }
        });
    })
}

m.loginUser = function (user, pwd, res) {
    loginModel.findOne({user: user}, function (err, doc) {
        if (err) {
            util.errResSend(res, err.message);
        }
        if (!doc) {
            return res.send(util.getResJson(501, "用户未注册"));
        }

        if (pwd == doc.pwd) {
            return res.send(util.getResJson(200, '登录成功'));
        } else {
            return res.send(util.getResJson(502, '密码不正确'));
        }
    });
}

module.exports = m;

新建login_define.js文件,填写代码如下:

/*
功能:定义常量
author:yang
date:2019/2/19
*/
let m = {
    DB_LOGIN_TABLE_NAME: 'login_db',    //mongodb登录model表名称

    WEB_SER_PORT: 3000,                //web服务端口号
    MG_DB_PORT: 27017,                 //mongodb端口号
    MG_DB_NAME: "testdb",              //mongodb实例名称
    INIT_ID: 10001,                    //默认玩家id
}

module.exports = m;

webserver文件目录下新建util文件目录:
mkdir utilcd util 新建util.js文件,填写代码如下:

/*
功能:扩展方法
author:yang
date:2019/2/19
*/
let m = {
    errResSend: function (res, errMsg) {
        return res.send('500', errMsg);
    },

    getResJson: function (code, ret) {
        let obj = {
            code: code,
            ret: ret,
        }
        return JSON.stringify(obj);
    },
};

module.exports = m;

到这里呢,我们的Express服务登录实现已经基本告一段落。
不过我们发现,login_define文件里,定义了一个常量WEB_SER_PORT,web服务端口号。为了用到它,我们打开www.js文件,修改代码如下:

......
let loginDefine = require('../models/login/login_define');
var port = normalizePort(process.env.PORT || loginDefine.WEB_SER_PORT.toString());
......

最后,我们回过头来看下,上面都做了写什么。现在我们可以得到项目文件如下:

bin						//web服务启动文件
data_base			//mongodb链接文件
models				//功能实现模块(实现了login模块的注册和登录)
node_modules	//插件或库安装目录
public					//好像是静态文件目录,暂时未用到
routes					//路由(处理http请求,实现了route_login路由)
util						//扩展文件(新建了util.js,主要用于路由处理请求时做的一些回调)
views					//暂未用到
app.js					//主文件
package.json		//插件或库安装记录文件
package-lock.json	//插件详细记录(个人感觉,不准确)

完整web服务文件下载 至此web登录服务改写完成。是不是感觉少些什么,还没调试呢!
预知后事如何,请看下篇分见。

下一篇:Node.js之Express(四) web登录服务:HTML5网页调试