1. 程式人生 > >【Node】nodejs+express+mongodb入門例項(二)

【Node】nodejs+express+mongodb入門例項(二)

一.目錄調整

基於上一個部分的內容,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('/')
}