【Node】nodejs+express+mongodb入門例項(二)
阿新 • • 發佈:2019-02-08
一.目錄調整
基於上一個部分的內容,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('/')
}