Node.js(express) + MongoDB(mongoose) 簡單開發(二)

前面說過,作一個真正意義上的登陸註冊,接下來就讓咱們一步一步實現吧~html

首先須要安裝mongodb,網上有不少安裝教程,這裏就再也不贅述。前端

安裝完成後開始與本地數據庫鏈接,能夠參考這裏:MongoDB介紹及下載與安裝node

最後能夠安裝一個可視化的操做數據庫的軟件:MongoVUE,配置也很簡單:git

image_thumb34_thumb_thumb

最後在項目級目錄下安裝mongoose,安裝過程自行百度~ 安裝成功後可在node_modules下看見mongoose文件夾github

接下來咱們測試數據庫是否連同:ajax

新建一個models的文件夾,在這裏咱們對錶進行操做(新建表,引用表)mongodb

在models下新建index.js:數據庫

var mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/blogData");

mongoose.connection.on("error", function (error){
    console.log("鏈接數據庫失敗"+error);
});

mongoose.connection.on("open", function (){
    console.log("數據庫鏈接成功!!!");
});

var tschema = new mongoose.Schema({
    name  : { type:String },
    date : {type: Date, default: Date.now}
});

var tmodel = mongoose.model("tdoc", tschema);

var testEntity = new tmodel({    name: "testUser"});testEntity.save(function (error, doc){    if(error){        console.log("error: "+error);    }else{        console.log(doc);    }});

tmodel.find({}, function (error, docs){
    if(error){
        console.log("error: "+error);
    }else{
        console.log(docs);
    }
});

exports.mongoose = mongoose;

這裏注意 添加事後把添加數據的地方給註釋起來,不然每執行一次都會添加一條數據。express

在IDE裏debug就能夠看到輸出的結果:json

image_thumb4_thumb

一樣咱們在可視化的數據管理軟件上也能夠看見:

image_thumb7_thumb

讓咱們精簡一下index.js的功能:

var mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/blogData");

exports.mongoose = mongoose;

創建一個login.js:

var mongodb = require("./index");

/*
* 用戶註冊
* */

var Schema = mongodb.mongoose.Schema;

var registerSchema = new Schema({
    username: {type: String},
    password: {type: String},
    createTime: {type: Date, default: Date.new}
});

var userModel = mongodb.mongoose.model("blogUser", registerSchema);

exports.userList = userModel;

這樣咱們就能夠在任何地方引用到userLsit了。

接下來在項目級目錄下建立一個dao的文件夾,這個文件夾的做用就是專門用來處理數據的。

在dao層,新建一個userDAO.js,在userDAO裏面封裝一些操做數據的方法:

var userModel = require("../models/login").userList;

var userDAO = function (){};

userDAO.prototype = {
    //
    save: function (json, callBack){
        var newUser = new userModel(json);

        newUser.save(function (err){
            callBack(err);
        });
    },
    //
    remove: function (json, callBack){
        userModel.remove(json, function (err){
            callBack(err);
        });
    },
    //
    update: function (json, condition, callBack){
        userModel.update(json, condition, function (err){
           callBack(err);
        });
    },
    //
    findByName: function (name, callBack){
        userModel.findOne({username: name}, function (err, doc){
            callBack(err, doc);
        });
    }
};

exports.userMethod = new userDAO();

這樣在須要操做數據的地方,咱們只需引用這個文件就能夠對數據庫進行操做了~

接下來讓咱們實現註冊的接口功能,接口的數據格式一樣沿用以前的數據格式。如今咱們已連通數據庫,因此用POST的方式

在C層新建login.js,在這個文件裏面寫註冊和登陸的方法:

var userMethod = require("../dao/userDAO").userMethod;

exports.register = function (req, res){
    userMethod.findByName(req.body.username, function (err, doc){
        if(!err){
            if(!doc){
                var newUser = {username: req.body.username, password: req.body.password};
                userMethod.save(newUser, function (err){
                    if(!err){
                        res.send({
                            code: 200,
                            msg: "註冊成功!(本條消息來自後臺)"
                        });
                    }
                });
            }else{
                res.send({
                    code: 201,
                    msg: "次用戶名已被佔用!(本條消息來自後臺)"
                });
            }
        }
    });
};

能夠看到思路也很簡單明確,用咱們以前封裝的查詢數據庫的方法,先對輸入的用戶名進行查詢,

當查詢沒有錯誤的時候再判斷,若是沒有查詢到這個用戶名,說明該用戶名還未註冊,反之該用戶名被佔用~

如今就能夠來實現前端的註冊功能了:

;(function ($){
    var foo = function (options){
        var self = this;
            self.options = $.extend({
                parent: $("#myForm"),
                register: $("[node-type=register]"),
                submit: $("[node-type=submit]")
            }, options);
        self.bindEvent();
    };

    foo.prototype = {
        bindEvent: function (){
            var self = this;
            self.register();
        },
        register: function (){
            var self = this,
                parent = self.options.parent,
                register = self.options.register;

            register.on("click", function (){
                var jqXML = $.ajax({
                    url: "/register",
                    dataType: "json",
                    type: "post",
                    data: parent.serialize()
                });

                jqXML.done(function (json){
                    if(json.code == 200){
                        alert(json.msg);
                    }else{
                        alert(json.msg);
                    }
                });
            });
        }
    };

    new foo();
})(jQuery);

一樣別忘了在longin.html頁面引用

最後在路由層新增註冊的接口:

//註冊接口
router.post("/register", loginController.register);

好了,接下來讓咱們重啓服務,看下一效果~

image_thumb2_thumb

image_thumb5_thumb

恭喜~ 註冊成功!

咱們能夠經過可視化的數據管理軟件看下咱們剛剛註冊的用戶,有沒有存儲到數據庫裏面:

image_thumb8_thumb

剛剛咱們註冊的用戶被完整的寫入到數據庫裏。

最後讓咱們按着寫註冊的思路,來實現一下登陸的功能吧~

首先在C層login.js裏面添加登陸功能:

exports.login = function (req, res){
    userMethod.findByName(req.body.username, function (err, doc){
        if(!err && doc && req.body.password === doc.password){
            res.send({code:200, msg:"成功(本條消息來自後臺)"});
        }else{
            res.send({"code":201, msg:"用戶名或者密碼錯誤(本條消息來自後臺)"});
        }
    });
    //if(req.body.username && req.body.password){
    //    res.send({code:200, msg: "登陸成功(本條消息來自後臺)"});
    //}else{
    //    res.send({code: 201, msg: "賬號或密碼錯誤(本條消息來自後臺)"});
    //}
};

登陸功能的思路也很簡單,先查詢用戶名,若是查詢未出錯,而且查詢到了輸入的用戶名,而且輸入的密碼與咱們數據庫存儲的密碼一致,

說明該用戶能夠正確的登陸。

前端的login.js新增登陸功能:

        bindEvent: function (){
            var self = this;
            self.login();
            self.register();
        },
        login: function (){
            var self = this,
                parent = self.options.parent,
                submit = self.options.submit;

            submit.on("click", function (){
                var jqXML = $.ajax({
                    url: "/userData",
                    dataType: "json",
                    type: "post",
                    data: parent.serialize()
                });

                jqXML.done(function (json){
                    if(json.code == 200){
                        location.href = "/home";
                    }else{
                        alert(json.msg);
                    }
                });
            });
        }

路由層index.js配置登陸接口:

//登陸接口
router.post("/userData", loginController.login);

OK~ 重啓服務,讓咱們來測試下咱們剛剛註冊的賬號是否能成功登陸~

image_thumb10_thumb

若是你能看到這個界面,那麼恭喜你,你的登陸功能也實現了~~

不過問題也來了:翻一下咱們曾寫的home.html就明白了,咱們寫的<%= username %>沒有正確被解析,仔細想下也不難理解:

咱們在沒有連用數據庫的時候,登陸是用get方式寫的,當時的實現思路是登陸後把用戶名存在了userList對象裏面,當咱們訪問home頁時再從這個對象裏面讀取用戶名,此時的<%= username %>徹底能夠被正確解析

可是問題是:如今咱們用的post方式,用戶名理所固然不會被存儲到userList裏面,固然就更沒有裏面的用戶名了。那麼咱們應該把用戶信息存儲到哪裏,當跳轉到home頁,能夠從這個地方直接讀取用戶信息呢?

接下來輪到他登場:express-session

安裝模塊express-session並引用,安裝、引用不在講述。 express-session詳解請戳這裏 什麼是session

在app.js裏使用新模塊進行訪問時間限制,以下:

var session = require('express-session');

//set session
app.use(session({
  secret: "secret",
  resave: true,
  saveUninitialized: false,
  cookie: {
    maxAge: 1000 * 60 * 10 //過期時間設置(毫秒)
  }
}));

必定要注意書寫順序,把app.use(session({}))寫在app.use('/', routes)的上面,緣由是中間件必須放在HTTP動詞方法以前,不然不會執行。

接下來新增中間件並設置模板變量值。這裏又涉及到一個新的名詞:中間件。什麼是中間件? 可一看下這裏 express之路由與中間件

其實咱們理解的中間件,就是一個個的組件,一個個的功能,都集成到middleware裏面,這樣作的好處就是調理清晰,思路明確

好了,咱們在項目級目錄下新建一個middleware文件夾,在裏面新建一個session.js,代碼以下:

exports.session = function (req, res, next){
    res.locals.user = req.session.user;
    var err = req.session.error;
    res.locals.message = "";
    if(err){
        res.locals.message = "<div style=\"margin-bottom: 20px; color: #f00;\">"+err+"</div>"
    }
    next();
};

在路由層的index.js添加對session模板的使用:

var session = require("../middleware/session");

router.use(session.session);

而後對登陸功能增長一些代碼:

exports.login = function (req, res){
    userMethod.findByName(req.body.username, function (err, doc){
        if(!err && doc && req.body.password === doc.password){
            var user = {
                username: req.body.username,
                password: req.body.password
            };
            req.session.user = user;
            res.send({code:200, msg:"成功(本條消息來自後臺)"});
        }else{
            res.send({"code":201, msg:"用戶名或者密碼錯誤(本條消息來自後臺)"});
        }
    });
    //if(req.body.username && req.body.password){
    //    res.send({code:200, msg: "登陸成功(本條消息來自後臺)"});
    //}else{
    //    res.send({code: 201, msg: "賬號或密碼錯誤(本條消息來自後臺)"});
    //}
};

在登陸成功後,咱們把用戶名以及密碼都存儲到user對象裏面,並把user對象賦給session下面的一個自定義對象user

在訪問home頁的時候咱們就能夠從session裏面讀取用戶信息了:

/* GET home page. */
router.get('/home', function (req, res){
    if(req.session.user){
        res.render("home", {
            title: "登陸成功頁",
            username:req.session.user["username"]
        });
    }else{
        req.session.error = "請先登陸";
        res.redirect("login");
    }
  //res.render('home', {
  //    title: "登陸成功頁",
  //    username: getLoginController.userList().username
  //});
});

判斷session下是否有user這個對象,有的話從user裏面讀取用戶信息,不然直接跳轉到登陸頁。

好了,到這就所有改寫完了,重啓服務,用註冊過的用戶名繼續測試:

image_thumb12_thumb

測試經過!而且能夠從session裏讀取到用戶信息,輸入一個沒註冊過的用戶:

image_thumb14_thumb

而且當咱們直接訪問home頁是,若是session裏有用戶信息,那麼能夠直接登陸,不然就會跳轉到登陸頁

還記不記得咱們當初還寫了一個登出的按鈕,如今簡單的寫一下登出的功能:

/*GET logout page.*/
router.get('/logout', function (req, res){
    req.session.user = null;
    req.session.error = null;
    res.redirect("/login");
});

登出的時候清空session的信息,並跳轉到登陸頁。

重啓服務進行測試,點退出登陸後能夠看到返回到了登陸頁

此時咱們再直接訪問home頁,因爲session信息已被清除,因此也直接跳轉到了登陸頁~ 大功告成!!!

 

至此,咱們整個的登陸註冊的功能就算是告一段落,能夠發現,其中任何一塊寫起來都沒有難度,難的是將他們以前串聯起來,難的是這個總體架構的思路思惟,因此平時仍是要多思考,

把總體的邏輯思路弄通了,那問題也就天然而然的解決了~

無代碼,無真相~ 代碼請戳這裏!

相關文章
相關標籤/搜索