【Node】nodejs+express+mongodb入门实例(一)
http://blog.csdn.net/whuzxq/article/details/73105978
一.目录调整
基于上一个部分的内容,app.js部分过于臃肿,不利于管理,因此对目录结构作出一些调整,让整个项目更符合MVC模式。
首先,新建config文件夹,并将路由相关的内容移入新建的route.js中。效果如下:
之前在app.js中的结构改成:
require('./config/routes')(app)
之后,继续对config.js的内容进行调整,改成mvc的格式:新建app文件夹,将models和schemas文件夹放入进去,并新建controller文件夹,在该文件夹中创建index.js,movie.js,user.js等,分别存放处理相应对象的方法。具体的目录结构如下图所示:
config.js变成了
以此完成了目录格式的优化。
二.用户登陆注册
注:hash算法:不可逆的,把任意长度的数据转化成固定的指纹
会话:用来跟踪用户,确定用户的身份。
session:当程序需要为客户端的请求创建session的时候,服务器首先检查客户端里面是否包含一个seesion的标示(sessionid),服务器根据此把它找出来,否则创建一个sessionid。保存sessionid可以放在cookie。一般情况下session存在内存里,若设置了session持久化的特性,那么清空内存后可以再次使用。
1.界面
lock content
.container
.row
.col-md-5
form(method="POST", action="/user/signup")//这里,定义路由。
.modal-body
.form-group
label(for="signupName") 用户名
input#signupName.form-control(name="user[name]", type="text")
.form-group
label(for="signupPassword") 密码
input#signupPassword.form-control(name="user[password]", type="text")
.modal-footer
button.btn.btn-default(type="button", data-dismiss="modal") 关闭
button.btn.btn-success(type="submit") 提交
2.服务器端:
exports.signup = function(req, res) {
var _user = req.body.user
User.findOne({name: _user.name}, function(err, user) {
if (err) {
console.log(err)
}
if (user) {
return res.redirect('/signin')
}//如果user存在,则重定向到登陆。
else {
user = new User(_user)//新建user对象
user.save(function(err, user) {
if (err) {
console.log(err)
}
res.redirect('/')//跳转回首页
})
}
})
}
3.schema:
var mongoose = require('mongoose')
var bcrypt = require('bcrypt')//加密密码
var SALT_WORK_FACTOR = 10
var UserSchema = new mongoose.Schema({
name: {
unique: true,
type: String
},
password: String,
// 0: nomal user
// 1: verified user
// 2: professonal user
// >10: admin
// >50: super admin
role: {
type: Number,
default: 0
},
meta: {
createAt: {
type: Date,
default: Date.now()
},
updateAt: {
type: Date,
default: Date.now()
}
}
})
UserSchema.pre('save', function(next) {
var user = this
if (this.isNew) {
this.meta.createAt = this.meta.updateAt = Date.now()
}
else {
this.meta.updateAt = Date.now()
}
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err)
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err)
user.password = hash
next()
})
})
})
//对象调用
UserSchema.methods = {
comparePassword: function(_password, cb) {
bcrypt.compare(_password, this.password, function(err, isMatch) {
if (err) return cb(err)
cb(null, isMatch)
})
}
}
//模型可以直接调用
UserSchema.statics = {
fetch: function(cb) {
return this
.find({})
.sort('meta.updateAt')
.exec(cb)
},
findById: function(id, cb) {
return this
.findOne({_id: id})
.exec(cb)
}
}
module.exports = UserSchema
三.用户登陆
1.界面
block content
.container
.row
.col-md-5
form(method="POST", action="/user/signin")
.modal-body
.form-group
label(for="signinName") 用户名
input#signinName.form-control(name="user[name]", type="text")
.form-group
label(for="signinPassword") 密码
input#signinPassword.form-control(name="user[password]", type="text")
.modal-footer
button.btn.btn-default(type="button", data-dismiss="modal") 关闭
button.btn.btn-success(type="submit") 提交
2.服务器端
// signin
exports.signin = function(req, res) {
var _user = req.body.user
var name = _user.name
var password = _user.password
User.findOne({name: name}, function(err, user) {
if (err) {
console.log(err)
}
//若用户不存在
if (!user) {
return res.redirect('/signup')
}
//比较密码是否相同
user.comparePassword(password, function(err, isMatch) {
if (err) {
console.log(err)
}
if (isMatch) {
req.session.user = user//设定session
return res.redirect('/')//若相同,则设置session,并重定向到首页
}
else {
return res.redirect('/signin')
}
})
})
}
在最开始,要检验session是否存在
// pre handle user
app.use(function(req, res, next) {
var _user = req.session.user
next()//啥时候写next啥时候不写?晕
})
app.js
app.use(express.cookieParser())//session本身依赖这个包
app.use(express.session({
secret: 'imooc',
}))//用session之前要引入
三.用户注销
// logout
exports.logout = function(req, res) {
delete req.session.user
//delete app.locals.user
res.redirect('/')
}