express 4.0 使用mongoose实现注册登录功能
发布于 9 年前 作者 chenjsh36 12271 次浏览 最后一次编辑是 8 年前 来自 分享

express 4.0 相对3.0 将很多非必要的插件都抽离开,如cookie、session等,需要我们自己去安装插件再使用 例如: cookieParser = require(‘cookie-parser’); app.use(cookieParser());

mongoose是基于mongodb开发出来一个数据库工具,它使用scheme、model、entity三个概念来具象化mongoose,并封装了mongodb的一些函数,使得我们操作数据库更方便快捷

在查询数据库情况时使用了robmongo这个可视化工具,不用再在终端敲代码查看情况,节省了很多时间

首先,项目的目录如下: -model –user.js -module –setting.js -routes -account.js -views –info.jade –login.jade –reg.jade -node_modules server.js package.json

model 存放mongoose定义的collection对象和方法, module为自己定义的一些模块, routes则是路由(将路由分块管理有利于后期的维护), views则是模板使用的文件所在文件夹

定好项目的基本目录后,写一个基本的服务器,设置好服务器渲染时候的模板引擎类型、路径、静态资源路径、路由功能以及监听定好的端口:

/* Module dependence */ var express = require(‘express’) , path = require(‘path’) // 第三方中间件 , connect = require(‘connect’) // 第三方中间件 , cookieParser = require(‘cookie-parser’) // cookie解析中间件 , account_r = require(’./routes/account’) // 用户登录、注册、退出路由 ;

/* Create server */ var app = express();

/* Set options */ app.set(‘view engine’, ‘jade’); // 模板引擎 app.set(‘views’, __dirname + ‘/views’); // 模板引用路径 // console.log(‘app_views:’, app.set(‘views’));

app.enable(‘trust proxy’); // 查看源IP地址使用

/**

  • Use cookie */ app.use(cookieParser());

/* Route */

// 用户登陆、注册、退出 app.use(’/user’, account_r);

// 为静态文件添加路径 app.use(’/static’, express.static(‘public’));

/* Listen at port and host */ var port = 3080; var server = app.listen(port, function(){ var host = server.address().address; var port = server.address().port; console.log(‘App listening at http://%s:%s’, host, port); });

启动服务器:node server.js 就能看到终端已经在监听服务器,但如果在浏览器端输入localhost:3080,会出现cannot get /的情况,因为路由还没有定义好,接下来我们来定义路由文件’routes/accout.js’和数据库文件’model/user.js’ user.js:

/**

  • 数据库定义 */

/**

  • 模块依赖
  • @type {module} */ var express = require(‘express’) , mongoose = require(‘mongoose’) ;

var Schema = mongoose.Schema; // 数据库地址,newexpress 为数据库名称 url = ‘mongodb://127.0.0.1:27017/newexpress’ /* Exports and Create Server */ var connect = mongoose.connect(url);

// 定义对象模型 var UserScheme = new Schema({ real_name: {type: String, default: ‘匿名’}, password: {type: String, default: ‘123’}, mail: {type: String, default: ‘’}, birth: {type: Date, default: Date.now}

});

// 访问user对象 // (注意)NOTE: methods must be added to the schema before compiling it with mongoose.model() UserScheme.methods.speak = function() { var greeting = this.real_name ? 'My name is ’ + this.real_name : ‘I don’t have a name…’; console.log(greeting); }

mongoose.model(‘User’, UserScheme); var User = mongoose.model(‘User’);

// 暴露connect接口 exports.connect = function(callback) { console.log(‘user_db connect’); // mongoose.connect(url); return connect; } exports.disconnect = function(callback) { console.log(‘user_db disconnect!’); mongoose.disconnect(callback); }

exports.setup = function(callback) { callback(null); }

exports.add = function(user, callback) { var new_user = new User(); new_user.real_name = user.real_name; new_user.password = user.password; new_user.mail = user.mail; new_user.birth = user.birth;

new_user.save(function(err) {
    if (err) {
        callback(err);
    } else {
        callback(null);
    }
});

}

exports.delete = function(id, callback) { exports.findUserById(id, function(err, doc) { if (err) { callback(err); } else { doc.remove(); callback(null); } }); }

exports.editMs = function(id, key, val, callback) { exports.findUserById(id, function(err, doc) { if (err) { callback(err); } else { doc.key = val; doc.save(function(err) { if (err) { callback(err); } else { callback(null); } }) } }); }

exports.allToUser = function(callback) { User.find({}, callback); }

exports.forAll = function(doEach, done) { User.find({}, function(err, docs) { if (err) { done(err,null); } docs.forEach(function(doc) { doEach(null, doc); }); done(null); }); }

exports.findUser = function(user, done) { console.log(‘findUser:’, user); User.find(user, function(err, doc) { if (err) { console.log(‘findUser: is err’); done(err, null); } else { console.log(‘findUser: no err’); done(null, doc); } }) }

var findUserById = exports.findUserById = function(id, callback) { User.findOne({_id: id}, function(err, doc) { if (err) { callback(err, null); } callback(null, doc); }); }

然后定义accout.js:

/* Module require */ var express = require(‘express’) , bodyParser = require(‘body-parser’) , multer = require(‘multer’) , user_db = require(’./…/model/user.js’) ;

/* Exports and Create Server */ var app = module.exports = express();

var upload = multer();// for parsing multipart/form-data

/**

  • Use middler 第三方中间件 */ app.use(bodyParser.json()); // for parsing application/json app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

/**

  • Middleware */

/**

  • 打印请求信息

  • @param {http} req 请求

  • @param {http} res 响应

  • @param {func} next 继续下一个请求

  • @return {}
    */ var logRequestMs = function (req, res, next) {

    console.log(’============================== 请求信息 =====================================================’); console.log(‘请求地址:’, req.path); // 打印ip地址,获取ip地址列表 console.log(‘远程ip地址为:’, req.ip); // 当trust proxy为true,解析X-Forwarded-For获取ip地址列表,否则值为空数组。 console.log(‘远程ips地址为:’, req.ip); console.log(‘请求的cookie:’, req.cookies); // 打印当前时间 var now = new Date(); console.log(‘请求时间:’, now.getYear() - 100 + ‘年’ + (now.getMonth() + 1) + ‘月’ + now.getHours() + ‘时’ + now.getMinutes() + ‘分’ + now.getSeconds() + ‘秒’);

    console.log(’================================结束请求信息===================================================’); next(); };

var listAll = function (fn) { user_db.allToUser(function(err, doc) { if (err) { console.log(‘err’); } else { console.log(‘ok’); doc.forEach(function(doc) { console.log(’_id:’, doc._id) console.log('real_name ', doc.real_name); console.log('password ', doc.password); console.log('birth ', doc.birth); console.log('mail ', doc.mail); }) } }); }

/**

  • 设置cookie
  • @param {http} res 响应
  • @param {string} name cookie名称
  • @param {string or obj} val cookie值
  • @param {int} expire 持续时间 */ var setCookie = function (res, name, val, expire) { var days = expire * 24 * 60 * 60; res.cookie(name, val, { expires: new Date(Date.now() + days), // signed: true // signed 设置后报错 }); }

/**

  • 删除cookie
  • @param {http} res res
  • @param {string} name cookie name
  • @return {}
    */ var delCookie = function (res, name) { res.clearCookie(name); }

/**

  • 获取cookie
  • @param {[type]} err [description]
  • @param {[type]} req [description]
  • @param {[type]} name [description]
  • @return {[type]} [description] */ var getCookie = function (req, key) { // if (req.signedCookie[name]) { // return req.signedCookie[name]; // } // else { // return null; // } if (typeof req.cookies[key] !== ‘undefined’) { return req.cookies[key]; } return undefined; }

/**

  • 使用应用级中间件 */ app.use(logRequestMs);

/**

  • Router 使用路由级中间件 */

// 注册页面 app.get(’/reg’, function(req, res) { res.render(‘reg’, {title: ‘注册’}); });

// 注册请求 app.post(’/reg’, function(req, res) { var username_ = req.body.username , password_ = req.body.password ; var register_user = { real_name: username_, password: password_, mail: ‘’, birth: new Date() }; user_db.findUser({real_name: username_}, function(err, doc) { if (err) { console.log('not found, and err is ', err.errors); } else { console.log(‘no err, and find user is ‘, doc, doc.length); if (doc.length === 0) { // 该用户名还未被注册 user_db.add(register_user, function(err) { if (err) { res.render(‘reg’, {success: false, err: err.errors}); } else { res.redirect(’/user/login’); } }); } else { console.log(‘用户名已经存在!’); res.render(‘reg’, {success: false, err: ‘用户名已经存在’}); } } })

});

// 登陆页面 app.get([’/’, ‘/login’], function (req, res, next) { var isLogin = false, username = ‘’ ; username = getCookie(req, ‘username’); if (typeof username !== ‘undefined’) { isLogin = true; username = req.cookies.username; } res.render(‘login’, {authenticated: isLogin, username: username}); });

// 登陆请求 app.post(’/login’, upload.array(), function (req, res, next) { var username_ = req.body.username , password_ = req.body.password ; // username: cjs, password: 123456 var search_user = { real_name: username_, password: password_ }; user_db.findUser(search_user, function(err, doc) { if (err) { console.log(err); delCookie(res, ‘username’); res.redirect(’/user’, {success: false, err: err.errors}); } else { console.log(‘pass auth’); setCookie(res, ‘username’, search_user.real_name, 30); res.redirect(’/user/info’); } }); });

// 登出页面 app.get(’/logout’, function(req, res) { delCookie(res, ‘username’); res.redirect(’/user/login’); });

// 测试页面 app.get(’/info’, function (req, res, next) { var isLogin = false, username = undefined ; username = getCookie(req, ‘username’); if (typeof username !== ‘undefined’) { isLogin = true; } res.render(‘info’, {authenticated: isLogin, username: username}) });

app.get(’/badreq’, function (req, res, next) { res.status(400).send(‘Bad request’); });

这样,就写好对应的路由逻辑,最后,在实现模板就可以了: 在views文件夹中添加info.jade、login.jade、reg.jade login.jade: div.sidebar a(href="/user/reg") 注册 if (authenticated) a(href="/user/logout") 退出 else a(href="/user/login") 登录 a(href="/user/info") 主页 div.content if (authenticated) p welcome back, #{username} else h1 User Login form(action="/user/login", method=“POST”) label Username input(type=“text”, name=“username”) label Password input(type=“password”, name=“password”) input(type=“submit”)

reg.jade: div.sidebar a(href="/user/reg") 注册 a(href="/user/login") 登录 a(href="/user/info") 主页 div.content h1 To register if (success == false) .err #{err} form(action="/user/reg", method=“post”) label(for=“username”) username input(type=“text” name=“username”)

        label(for="password") password
        input(type="password" name="password")

        label(for="confirm_password") confirm password
        input(type="password")

        input(type="submit" value="submit")

info.jade div.sidebar a(href="/user/reg") 注册 if (authenticated) a(href="/user/logout") 退出 else a(href="/user/login") 登录 a(href="/user/info") 主页 div.content if (authenticated) h1 这是主页, #{username} else h1 这是主页,请先登录

样式就不再贴出,这样在浏览器输入http://localhost:3080/user/login 就可以看到登录的页面,至此实现了基本的逻辑功能

4 回复

能格式化一下么?

楼主你滴让我看花眼

代码如何不知道…格式不堪入目,这哥们也不回头编辑一下…

哥们你这教程写的这么直白的么。

回到顶部