NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证

 

  JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许JS使用运行环境提供的内置对象和方法做一些事情。例如运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象。而运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS就相应提供了fs、http等内置对象。Express作为NodeJS的Web应用框架,可以帮助我们快速开发Web网站。


  开发环境

  • NodeJS:v0.10.30
  • npm:1.4.21
  • OS:Win7旗舰版 32bit
  • Express:4.2.0
  • MongoDB:2.6.3
E:\project> node -v
v0.10.30
E:\project> npm -v
1.4.21
E:\project> express -V
4.2.0

  1、建立工程

  使用express命令建立工程,并支持ejs:

E:\project> express -e nodejs-demo

   create : nodejs-demo
create : nodejs-demo/package.json
create : nodejs-demo/app.js
create : nodejs-demo/public
create : nodejs-demo/public/javascripts
create : nodejs-demo/public/images
create : nodejs-demo/public/stylesheets
create : nodejs-demo/public/stylesheets/style.css
create : nodejs-demo/routes
create : nodejs-demo/routes/index.js
create : nodejs-demo/routes/users.js
create : nodejs-demo/views
create : nodejs-demo/views/index.ejs
create : nodejs-demo/views/error.ejs
create : nodejs-demo/bin
create : nodejs-demo/bin/www install dependencies:
$ cd nodejs-demo && npm install run the app:
$ DEBUG=nodejs-demo ./bin/www E:\project>

  根据提示下载依赖包:

E:\project> cd .\nodejs-demo
E:\project\nodejs-demo> npm install
npm WARN deprecated static-favicon@1.0.2: use serve-favicon module
static-favicon@1.0.2 node_modules\static-favicon debug@0.7.4 node_modules\debug ejs@0.8.8 node_modules\ejs cookie-parser@1.0.1 node_modules\cookie-parser
├── cookie-signature@1.0.3
└── cookie@0.1.0 morgan@1.0.1 node_modules\morgan
└── bytes@0.3.0 body-parser@1.0.2 node_modules\body-parser
├── qs@0.6.6
├── raw-body@1.1.7 (bytes@1.0.0, string_decoder@0.10.25-1)
└── type-is@1.1.0 (mime@1.2.11) express@4.2.0 node_modules\express
├── parseurl@1.0.1
├── utils-merge@1.0.0
├── cookie@0.1.2
├── merge-descriptors@0.0.2
├── escape-html@1.0.1
├── range-parser@1.0.0
├── fresh@0.2.2
├── cookie-signature@1.0.3
├── debug@0.8.1
├── methods@1.0.0
├── buffer-crc32@0.2.1
├── serve-static@1.1.0
├── path-to-regexp@0.1.2
├── qs@0.6.6
├── send@0.3.0 (debug@0.8.0, mime@1.2.11)
├── accepts@1.0.1 (negotiator@0.4.7, mime@1.2.11)
└── type-is@1.1.0 (mime@1.2.11)
E:\project\nodejs-demo>

  工程建立成功,启动服务:

E:\project\nodejs-demo> npm start

> nodejs-demo@0.0.1 start E:\project\nodejs-demo
> node ./bin/www

  本地3000端口被打开,在浏览器地址栏输入localhost:3000,访问成功。


  2、目录结构

  • bin——存放命令行程序。
  • node_modules——存放所有的项目依赖库。
  • public——存放静态文件,包括css、js、img等。
  • routes——存放路由文件。
  • views——存放页面文件(ejs模板)。
  • app.js——程序启动文件。
  • package.json——项目依赖配置及开发者信息。
E:\project\nodejs-demo> dir

    目录: E:\project\nodejs-demo

Mode                LastWriteTime     Length Name
---- ------------- ------ ----
d---- 2014/8/16 21:55 bin
d---- 2014/8/16 22:03 node_modules
d---- 2014/8/16 21:55 public
d---- 2014/8/16 21:55 routes
d---- 2014/8/16 21:55 views
-a--- 2014/8/16 21:55 1375 app.js
-a--- 2014/8/16 21:55 327 package.json

  3、Express配置文件

  打开app.js:

 1 var express = require('express');
2 var path = require('path');
3 var favicon = require('static-favicon');
4 var logger = require('morgan');
5 var cookieParser = require('cookie-parser');
6 var bodyParser = require('body-parser');
7
8 var routes = require('./routes/index');
9 var users = require('./routes/users');
10
11 var app = express();
12
13 // view engine setup
14 app.set('views', path.join(__dirname, 'views'));
15 app.set('view engine', 'ejs');
16
17 app.use(favicon());
18 app.use(logger('dev'));
19 app.use(bodyParser.json());
20 app.use(bodyParser.urlencoded());
21 app.use(cookieParser());
22 app.use(express.static(path.join(__dirname, 'public')));
23
24 app.use('/', routes);
25 app.use('/users', users);
26
27 /// catch 404 and forward to error handler
28 app.use(function(req, res, next) {
29 var err = new Error('Not Found');
30 err.status = 404;
31 next(err);
32 });
33
34 /// error handlers
35
36 // development error handler
37 // will print stacktrace
38 if (app.get('env') === 'development') {
39 app.use(function(err, req, res, next) {
40 res.status(err.status || 500);
41 res.render('error', {
42 message: err.message,
43 error: err
44 });
45 });
46 }
47
48 // production error handler
49 // no stacktraces leaked to user
50 app.use(function(err, req, res, next) {
51 res.status(err.status || 500);
52 res.render('error', {
53 message: err.message,
54 error: {}
55 });
56 });
57
58
59 module.exports = app;

  4、Ejs模板

  修改app.js,让ejs模板文件使用扩展名为html的文件:

13 // view engine setup
14 app.set('views', path.join(__dirname, 'views'));
15 //app.set('view engine', 'ejs');
16 app.engine('html', require('ejs').renderFile);
17 app.set('view engine', 'html');

  修改完成后,重命名views/index.ejs为views/index.html。重启服务,访问成功。


  5、安装常用库及页面分离

  添加bootstrap和jQuery:

E:\project\nodejs-demo> npm install bootstrap
bootstrap@3.2.0 node_modules\bootstrap
E:\project\nodejs-demo> npm install jquery
jquery@2.1.1 node_modules\jquery
E:\project\nodejs-demo>

  接下来,把index.html分成三个部分:

  • header.html——页面头部区域。
  • index.html——页面内容区域。
  • footer.html——页面底部区域。

  header.html

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <title><%= title %></title>
6 <!-- Bootstrap -->
7 <link href="/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen">
8 </head>
9 <body screen_capture_injected="true">

  index.html

1 <% include header.html %>
2 <h1><%= title %></h1>
3 <p>Welcome to <%= title %></p>
4 <% include footer.html %>

  footer.html

1     <script src="/javascripts/jquery.min.js"></script>
2 <script src="/javascripts/bootstrap.min.js"></script>
3 </body>
4 </html>

  重启服务,访问成功。


  6、路由

  登录设计:

访问路径 页面 描述
/ index.html 不需要登录,可以直接访问。
/home home.html 必须用户登录以后,才可以访问。
/login login.html 登录页面,用户名密码输入正确,自动跳转到home.html。
/logout 退出登录后,自动跳转到index.html。

  打开app.js文件,增加路由配置:

26 app.use('/', routes);
27 app.use('/users', users);
28 app.use('/login', routes);
29 app.use('/logout', routes);
30 app.use('/home', routes);

  打开routes/index.js文件,添加对应方法:

 1 var express = require('express');
2 var router = express.Router();
3
4 /* GET home page. */
5 router.get('/', function(req, res) {
6 res.render('index', { title: 'Express' });
7 });
8
9 router.route('/login')
10 .get(function(req, res) {
11 res.render('login', { title: '用户登录' });
12 })
13 .post(function(req, res) {
14 var user={
15 username: 'admin',
16 password: '123456'
17 }
18 if(req.body.username === user.username && req.body.password === user.password){
19 res.redirect('/home');
20 }
21 res.redirect('/login');
22 });
23
24 router.get('/logout', function(req, res) {
25 res.redirect('/');
26 });
27
28 router.get('/home', function(req, res) {
29 var user={
30 username:'admin',
31 password:'123456'
32 }
33 res.render('home', { title: 'Home', user: user });
34 });
35
36 module.exports = router;

  创建views/login.html和views/home.html两个文件:

  login.html

 1 <% include header.html %>
2 <div class="container">
3 <form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post">
4 <fieldset>
5 <legend>用户登录</legend>
6 <div class="form-group">
7 <label class="col-sm-3 control-label" for="username">用户名</label>
8 <div class="col-sm-9">
9 <input type="text" class="form-control" id="username" name="username" placeholder="用户名" required>
10 </div>
11 </div>
12 <div class="form-group">
13 <label class="col-sm-3 control-label" for="password">密码</label>
14 <div class="col-sm-9">
15 <input type="password" class="form-control" id="password" name="password" placeholder="密码" required>
16 </div>
17 </div>
18 <div class="form-group">
19 <div class="col-sm-offset-3 col-sm-9">
20 <button type="submit" class="btn btn-primary">登录</button>
21 </div>
22 </div>
23 </fieldset>
24 </form>
25 </div>
26 <% include footer.html %>

  home.html

1 <% include header.html %>
2 <h1>Welcome <%= user.username %>, 欢迎登录!!</h1>
3 <a class="btn" href="/logout">退出</a>
4 <% include footer.html %>

  修改index.html,增加登录链接:

1 <% include header.html %>
2 <h1>Welcome to <%= title %></h1>
3 <p><a href="/login">登录</a></p>
4 <% include footer.html %>

  路由及页面已准备好,重启服务,访问成功。


  7、session

  安装中间件express-session:

E:\project\nodejs-demo> npm install express-session
express-session@1.7.5 node_modules\express-session
├── cookie@0.1.2
├── cookie-signature@1.0.4
├── on-headers@1.0.0
├── utils-merge@1.0.0
├── parseurl@1.3.0
├── buffer-crc32@0.2.3
├── depd@0.4.4
├── debug@1.0.4 (ms@0.6.2)
└── uid-safe@1.0.1 (base64-url@1.0.0, mz@1.0.0)
E:\project\nodejs-demo>

  安装中间件connect-mongodb:

E:\project\nodejs-demo> npm install connect-mongodb
\ > kerberos@0.0.3 install E:\project\nodejs-demo\node_modules\connect-mongodb\nod
e_modules\mongodb\node_modules\kerberos
> (node-gyp rebuild 2> builderror.log) || (exit 0) |
E:\project\nodejs-demo\node_modules\connect-mongodb\node_modules\mongodb\node_mo
dules\kerberos>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\
..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild
|
> bson@0.2.11 install E:\project\nodejs-demo\node_modules\connect-mongodb\node_m
odules\mongodb\node_modules\bson
> (node-gyp rebuild 2> builderror.log) || (exit 0) E:\project\nodejs-demo\node_modules\connect-mongodb\node_modules\mongodb\node_mo
dules\bson>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\.
.\node_modules\node-gyp\bin\node-gyp.js" rebuild
connect-mongodb@1.1.5 node_modules\connect-mongodb
├── connect@1.9.2 (mime@1.2.11, formidable@1.0.15, qs@1.2.2)
└── mongodb@1.4.8 (kerberos@0.0.3, readable-stream@1.0.27-1, bson@0.2.11)
E:\project\nodejs-demo>

  安装中间件mongodb:

E:\project\nodejs-demo> npm install mongodb
- > kerberos@0.0.3 install E:\project\nodejs-demo\node_modules\mongodb\node_module
s\kerberos
> (node-gyp rebuild 2> builderror.log) || (exit 0) -
E:\project\nodejs-demo\node_modules\mongodb\node_modules\kerberos>node "C:\Progr
am Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\b
in\node-gyp.js" rebuild
|
> bson@0.2.11 install E:\project\nodejs-demo\node_modules\mongodb\node_modules\b
son
> (node-gyp rebuild 2> builderror.log) || (exit 0) E:\project\nodejs-demo\node_modules\mongodb\node_modules\bson>node "C:\Program F
iles\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\n
ode-gyp.js" rebuild
mongodb@1.4.8 node_modules\mongodb
├── kerberos@0.0.3
├── readable-stream@1.0.27-1 (isarray@0.0.1, string_decoder@0.10.25-1, inheri
ts@2.0.1, core-util-is@1.0.1)
└── bson@0.2.11 (nan@1.2.0)
E:\project\nodejs-demo>

  添加database/settings.js和database/msession.js这两个文件:

  settings.js

1 module.exports = {
2 COOKIE_SECRET: 'ywang1724.com',
3 URL: 'mongodb://127.0.0.1:27017/nodedb',
4 DB: 'nodedb',
5 HOST: '127.0.0.1',
6 PORT: 27017,
7 USERNAME: 'admin',
8 PASSWORD: '123456'
9 };

  msession.js

1 var Settings = require('./settings');
2 var Db = require('mongodb').Db;
3 var Server = require('mongodb').Server;
4 var db = new Db(Settings.DB, new Server(Settings.HOST, Settings.PORT, {auto_reconnect:true, native_parser: true}),{safe: false});
5
6 module.exports = db;

  修改app.js文件:

 1 var express = require('express');
2 var path = require('path');
3 var favicon = require('static-favicon');
4 var logger = require('morgan');
5 var cookieParser = require('cookie-parser');
6 var bodyParser = require('body-parser');
7
8 //采用connect-mongodb中间件作为Session存储
9 var session = require('express-session');
10 var Settings = require('./database/settings');
11 var MongoStore = require('connect-mongodb');
12 var db = require('./database/msession');
13
14 var routes = require('./routes/index');
15 var users = require('./routes/users');
16
17 var app = express();
18
19 // view engine setup
20 app.set('views', path.join(__dirname, 'views'));
21 //app.set('view engine', 'ejs');
22 app.engine('html', require('ejs').renderFile);
23 app.set('view engine', 'html');
24
25 app.use(favicon());
26 app.use(logger('dev'));
27 app.use(bodyParser.json());
28 app.use(bodyParser.urlencoded());
29 app.use(cookieParser());
30 //session配置
31 app.use(session({
32 cookie: { maxAge: 600000 },
33 secret: Settings.COOKIE_SECRET,
34 store: new MongoStore({
35 username: Settings.USERNAME,
36 password: Settings.PASSWORD,
37 url: Settings.URL,
38 db: db})
39 }))
40 app.use(function(req, res, next){
41 res.locals.user = req.session.user;
42 next();
43 });
44
45 app.use(express.static(path.join(__dirname, 'public')));
46
47 ......

  修改index.js文件:

 1 var express = require('express');
2 var router = express.Router();
3
4 /* GET home page. */
5 router.get('/', function(req, res) {
6 res.render('index', { title: 'Express' });
7 });
8
9 router.route('/login')
10 .get(function(req, res) {
11 res.render('login', { title: '用户登录' });
12 })
13 .post(function(req, res) {
14 var user = {
15 username: 'admin',
16 password: '123456'
17 }
18 if(req.body.username === user.username && req.body.password === user.password){
19 req.session.user = user;
20 res.redirect('/home');
21 } else {
22 res.redirect('/login');
23 }
24 });
25
26 router.get('/logout', function(req, res) {
27 req.session.user = null;
28 res.redirect('/');
29 });
30
31 router.get('/home', function(req, res) {
32 res.render('home', { title: 'Home' });
33 });
34
35 module.exports = router;

  本地安装数据库MongoDB,新建用户nodedb。重启服务,访问成功。


  8、页面访问控制及提示

  访问控制设计:

访问路径 描述
/ 任何人都可以访问,不需要认证。
/home 拦截get请求,调用authentication()进行认证,不通过则自动跳转到登录页面。
/login 任何人都可以访问,不需要认证。
/logout 任何人都可以访问,不需要认证。

  修改index.js文件:

34 router.get('/home', function(req, res) {
35 authentication(req, res);
36 res.render('home', { title: 'Home' });
37 });
38
39 function authentication(req, res) {
40 if (!req.session.user) {
41 return res.redirect('/login');
42 }
43 }

  重启服务,访问成功。

  添加页面提示,修改app.js文件,增加res.locals.message:

40 app.use(function(req, res, next) {
41 res.locals.user = req.session.user;
42 var err = req.session.error;
43 delete req.session.error;
44 res.locals.message = '';
45 if (err) {
46 res.locals.message = '<div class="alert alert-warning">' + err + '</div>';
47 }
48 next();
49 });

  修改index.js文件,增加req.session.error:

 1 var express = require('express');
2 var router = express.Router();
3
4 /* GET home page. */
5 router.get('/', function(req, res) {
6 res.render('index', { title: 'Express' });
7 });
8
9 router.route('/login')
10 .get(function(req, res) {
11 if (req.session.user) {
12 res.redirect('/home');
13 }
14 res.render('login', { title: '用户登录' });
15 })
16 .post(function(req, res) {
17 var user = {
18 username: 'admin',
19 password: '123456'
20 }
21 if (req.body.username === user.username && req.body.password === user.password) {
22 req.session.user = user;
23 res.redirect('/home');
24 } else {
25 req.session.error='用户名或密码不正确';
26 res.redirect('/login');
27 }
28 });
29
30 router.get('/logout', function(req, res) {
31 req.session.user = null;
32 res.redirect('/');
33 });
34
35 router.get('/home', function(req, res) {
36 authentication(req, res);
37 res.render('home', { title: 'Home' });
38 });
39
40 function authentication(req, res) {
41 if (!req.session.user) {
42 req.session.error='请先登录';
43 return res.redirect('/login');
44 }
45 }
46
47 module.exports = router;

  修改login.html,增加<%- message %>:

5 <legend>用户登录</legend>
6 <%- message %>
7 <div class="form-group">

  重启服务,访问成功。输入错误用户名密码:

图1 登录不成功提示

 
分类: nodejs

搭建开发框架Express,实现Web网站登录验证的更多相关文章

  1. NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证

    JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器.每一种解析器都是一个运行环境,不但允许J ...

  2. express+nodecoffee写passport登录验证实例(一)

    项目中要用到passport登录验证,环境如标题样:express框架,coffee模版引擎,node后台 一:建项目 直接用express命令建,虽然默认模版为jade,可以手动换成coffee哦. ...

  3. Java Web Filter登录验证

    初做网站需要登录验证,转自 :http://blog.csdn.net/daguanjia11/article/details/48995789 Filter: Filter是服务器端的组件,用来过滤 ...

  4. express+nodecoffee写passport登录验证实例(二)

    二:实现登录认证 passport官网文档:  http://passportjs.org/guide/ passport验证使用一种被称为“策略”的方式来验证请求,策略支持3种类型的验证:用户名密码 ...

  5. 用JSP实现WEB页面登录验证

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  6. node 搭建开发框架express

    参考地址: http://www.itnose.net/detail/6095003.html 开发环境 E:\project> node -v v0.10.30 E:\project> ...

  7. jquery登录验证插件

    最近写了个登录验证的jquery插件,其中功能还不是很完善,需要进一步改进,先放出来看看先. /** * 功能描述:本模块实现普通网站登录验证,以后可以添加二维码验证,以及第三方帐号登录验证 * 关联 ...

  8. ASP.NET Core 一步步搭建个人网站(4)_主页和登录验证

    上章节我们已经定制好动态配置的菜单,用户登录网站的第一步就是进入首页内容,那我们先搭建一下我们的首页内容.想着自己的网站内容主要是个人博客类型,所以,首页就展示博主本人的一些基本信息吧,哈哈.当然,做 ...

  9. Ubuntu下搭建NodeJS+Express WEB开发框架

    Ubuntu下搭建NodeJS+Express WEB开发框架 2012-12-27 15:06 作者: NodeJSNet 来源: 本站 浏览: 2,966 次阅读 我要评论暂无评论 字号: 大 中 ...

随机推荐

  1. avalonjs1.5 入门教程

    迷你MVVM框架 avalonjs1.5 入门教程 avalon经过几年以后,已成为国内一个举足轻重的框架.它提供了多种不同的版本,满足不同人群的需要.比如avalon.js支持IE6等老旧浏览器,让 ...

  2. Hadoop获得先进的步步高(四)-试Hadoop

    四.试Hadoop 一个简单的求每年温度最大值的程序. 1.准备两个文本測试数据 准备两个名为data1.txt及data2.txt的文件.用于做为计算的输入数据,将其放于/home/fenglibi ...

  3. (大数据工程师学习路径)第二步 Vim编辑器----Vim快速入门

    vim模式介绍 以下介绍内容来自维基百科Vim 从vi演生出来的Vim具有多种模式,这种独特的设计容易使初学者产生混淆.几乎所有的编辑器都会有插入和执行命令两种模式,并且大多数的编辑器使用了与Vim截 ...

  4. 在CentOS 7上安装phpMyAdmin

    原文 在CentOS 7上安装phpMyAdmin phpMyAdmin是一款以PHP为基础,基于Web的MySQL/MariaDB数据库管理工具.虽然已经存在着一些诸如Adminer的轻量级数据库管 ...

  5. 网络资源(7) - JAX-WS视频

    2014_08_25 http://v.youku.com/v_show/id_XNjMzNDcyMTk2.html 基于JAX-WS编程模型的WebService 1. @WebService注释类 ...

  6. flume日志采集

    1.  Log4j Appender 1.1.  使用说明 1.1.2.  Client端Log4j配置文件 (黄色文字为需要配置的内容) log4j.rootLogger=INFO,A1,R # C ...

  7. C++达到String分类

    这是一个非常经典的面试题,能够测试学生很短的时间C++法师是综合,答案应包含C++大多数知识类,保证书String符类可以完成值.抄.的变量和其它函数的定义. #include<iostream ...

  8. e.target 和 e.srcElement 的使用问题

    ie 下的event.srcElement从字面上可以看出来有以下关键字:事件.源(它的意思就是:当前事件的源), 我们可以调用他的各种属性就像:document.getElementById(&qu ...

  9. Android编码标准

    只是练习是很难找工作那会儿在,简历基本上都是赶出去石沉大海,因为有项目开发没有实践经验.没有牛逼的背景.更重要的是,没有真才实学,虽然我在大学时读的是计算机专业,它可以被认为是一个技术教育.但--你知 ...

  10. javascript中类的属性研究

    原文:javascript中类的属性研究 本篇文章主要针对javascript的属性进行分析,由于javascript是一种基于对象的语言,本身没有类的概念,所以对于javascript的类的定义有很 ...