这篇文章是“从零开始使用express搭建博客系统系列”的最后一篇文章
此文主要给大家分析一下此博客系统后台功能的搭建,我会分析几个我碰到的问题及常用的插件
具体的代码我就不一一贴上来了,大家可以参考:博客系统的源码。
效果如下:
一:后台的页面搭建
这里就不详细的叙述了,大家可以参考从零开始使用express搭建博客系统(二):博客前端实现的第一节前端页面的搭建,与前端的博客页面搭建类似,模板的话也是bootstrap
的dashboard
模板。
二:后台权限验证——登录注册功能实现
要实现后台的登录,则必须需要后后台验证,如果用户没有登录的时候,当我们访问后台首页的url
的时候,会自动跳转到登录页面,让用户进行登录。
如下图:
如果有账号,就进行账号登陆,如果没有账号,则进行用户注册,注册完成之后进行登录。
这个我们通常的做法就是根据是否有session
或者cookie
来判断用户是否登录,当用户登录之后,则存一个乡相应的session
。
在这个项目中,我们的认证是通过Express
结合Passport
来完成的。
-
首先我们安装
session
依赖:express-session
,cookie-parser
npm install express-session cookie-parser --save-dev // 在express.js中引入 var cookieParser = require('cookie-parser'); var session = require('express-session'); app.use(session({ secret: 'nodeblog', resave: false, saveUninitialized: true, cookie: { secure: false }, }));
通过上述代码,我们就可以在项目中使用
session
了。 -
安装
passport
1,首先进行安装:
npm install passport passport-local --save-dev //
2,然后我们在
config
文件下,我们建立一个passport.js
文件,实现定义认证策略。var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var mongoose = require('mongoose'), User = mongoose.model('User'); module.exports.init = function () { passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, done) { User.findOne({ email: email }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false); } if (!user.verifyPassword(password)) { return done(null, false); } return done(null, user); }); })); passport.serializeUser(function(user, done) { console.log('passport.local.serializeUser:', user); //打印,验证是否连接成功 done(null, user._id); }); passport.deserializeUser(function(id, done) { console.log('passport.local.deserializeUser:', id); //打印,验证是否连接成功 User.findById(id, function (err, user) { done(err, user); }); }); };
3,在我们的
express
中引入passport
var passport = require('passport'); // 验证登录 app.use(passport.initialize()); app.use(passport.session()); // 初始化,需要放在session之后 // 拿到相应的session app.use(function (req, res, next) { req.user = null; if (req.session.passport && req.session.passport.user) { User.findById(req.session.passport.user, function (err, user) { if (err) return next(err); user.password = null; // session将password隐去 req.user = user; next(); }) } else { next(); } });
4,接着我们只要在
controllers/admin/user.js
文件中的login
路由,加入passport
。如下图:
passport这样就能实现
login
的认证登录了,他会在用户实现登录这个操作的时候,通过passport
这个中间件方法,存储相应的session
。5,完成验证
session
这个方法,将其加在每一个后台页面的路由作为其中间键,完成验证。验证中间件验证中间件引用
通过以上步骤,我们便完成了用户的身份验证,对于passport
我这里没有讲的很详细,大家如果想深入了解的话可以参考:Express结合Passport实现登陆认证、Passport官网。
三:后台的功能的实现
后台的功能分为,目录与文章的增删改查,实际上后台逻辑的实现与前端显示相应的posts
很类似,都比较简单。
说白了,就是使用模型对数据库进行增删改查,这里大家主要看一下相应的路由结构。
-
posts
的路由如下:posts路由这里主要实现的是文章的增删改查。
-
categoties
的路由如下:categoties路由与文章增删改查基本上一样,只不过换了一个
model
,查了一个不同的表。
后台逻辑实现的时候,有几个小点我提一下:
-
添加和删除,其实是公用一套模板
这个应该大多数的开发者都清楚,区别就是在调用模板的时候,传不传入文章的
id
的关系,如果传入了文章的Id,就显示对应的文章内容;反之,直接显示空白的模板。 -
引入词组智能匹配最正确的拼音——
pinyin
针对中文会出现错误这一问题,这个我引入了一个依赖,根据词组智能匹配最正确的拼音——
pinyin
pinyin = require('pinyin'); var py = pinyin(name, { style: pinyin.STYLE_NORMAL, //普通风格,不带音标 heteronym: false //启用多音字模式 })
转化之后的
py
是一个数组,我们可以用map
方法数组进行处理。pinyin使用具体的api大家可以参考
pinyin
的github
文档:pinyin。 -
函数
getCategoryById
针对增删改查都是对于某一个数据的操作,我们抽离了一个函数
getCategoryById
作为公用的函数,因为node
支持中间件,我们可以将这个函数作为中间件加到相应的路由中去,然后将得到的目录挂到req
下,方便我们之后的函数调用。getCategoryById方法
四:需要注意的点
1,图标的使用
这里我们使用font-awesome,我们通过bower
下载:
bower install font-awesome --save
通过bower
会自动下载到public
文件夹下
然后在需要用到的jade
文件中引入,如下图:
2,编辑器的引入
我们使用轻量级的编辑器ckeditor,我们可以进到官网下载包,并将包放在public/js
下,如图:
接着就是使用这个编辑器了,我们在添加文章的jade
文件中,引入ckeditor.js
:
接着给编辑器的id
加上一段代码就可以实现编辑器了:
3,表单验证依赖的引入:express-validator
这个很方便,我们只要引入一个依赖,然后应用就可以实现简单的表单验证。
npm install express-validator --save-dev
接着在express.js
中引入并使用此依赖。
最后在jade文件中相应的表单上加上required="true"
就可以了。
这样当我们输入的值为空或者不符合规范的时候就会有相应的提示了:
五:总结
到这里我们使用express
搭建博客系统就完成了,可能还有很多细节我没有涉及到,以及一些错误,大家如果发现问题,欢迎简信交流哦。
其实这是一个很简单的例子,仅仅是使用node
对数据库进行增删改查,没有设计到特别复杂的逻辑。大家就把这个当作express
的一个入门,这也仅仅是一个学node
的开始。
当初自己学习express
的目的就是因为它能快速的帮我上手web
项目,只需要掌握关于node
的简单基础知识就行了,但是在项目的过程开发中,我逐渐发现自己对于node
的基础掌握的还不扎实,需要恶补一下。
最后,希望这篇文章对大家能有帮助,来自一个奔跑在前端路上的前端小白。