前面说过,作一个真正意义上的登陆注册,接下来就让咱们一步一步实现吧~html
首先须要安装mongodb,网上有不少安装教程,这里就再也不赘述。前端
安装完成后开始与本地数据库链接,能够参考这里:MongoDB介绍及下载与安装node
最后能够安装一个可视化的操做数据库的软件:MongoVUE,配置也很简单:git
最后在项目级目录下安装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
一样咱们在可视化的数据管理软件上也能够看见:
让咱们精简一下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);
好了,接下来让咱们重启服务,看下一效果~
恭喜~ 注册成功!
咱们能够经过可视化的数据管理软件看下咱们刚刚注册的用户,有没有存储到数据库里面:
刚刚咱们注册的用户被完整的写入到数据库里。
最后让咱们按着写注册的思路,来实现一下登陆的功能吧~
首先在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~ 重启服务,让咱们来测试下咱们刚刚注册的账号是否能成功登陆~
若是你能看到这个界面,那么恭喜你,你的登陆功能也实现了~~
不过问题也来了:翻一下咱们曾写的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里面读取用户信息,不然直接跳转到登陆页。
好了,到这就所有改写完了,重启服务,用注册过的用户名继续测试:
测试经过!而且能够从session里读取到用户信息,输入一个没注册过的用户:
而且当咱们直接访问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信息已被清除,因此也直接跳转到了登陆页~ 大功告成!!!
至此,咱们整个的登陆注册的功能就算是告一段落,能够发现,其中任何一块写起来都没有难度,难的是将他们以前串联起来,难的是这个总体架构的思路思惟,因此平时仍是要多思考,
把总体的逻辑思路弄通了,那问题也就天然而然的解决了~
无代码,无真相~ 代码请戳这里!