您的位置:首页 > 运维架构 > 网站架构

搭建开发框架Express,实现Web网站登录验证

2016-07-19 16:10 886 查看
声明: 本文不是原创,作者HackerVirus,[]http://www.cnblogs.com/Leo_wl/p/3920907.html],因代码未高亮,阅读吃力,所以翻抄。原博主有大量好文,建议前去拜访(本人向来厌恶抄袭泛滥)。

开发环境

NodeJS:v0.10.30

npm:1.4.21

OS:Win7旗舰版 32bit

Express:4.2.0

MongoDB:2.6.3

建立工程

使用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,访问成功。

目录结构

bin——存放命令行程序。

node_modules——存放所有的项目依赖库。

public——存放静态文件,包括css、js、img等。

routes——存放路由文件。

views——存放页面文件(ejs模板)。

app.js——程序启动文件。

package.json——项目依赖配置及开发者信息。

Express配置文件

打开app.js:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});

module.exports = app;


Ejs模板

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

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


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

安装常用库及页面分离

添加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

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


index.html

<% include header.html %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<% include footer.html %>


footer.html

<script src="/javascripts/jquery.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
</body>
</html>


重启服务,访问成功。

路由

 登录设计:

 

访问路径页面描述
/index.html不需要登录,可以直接访问。
/homehome.html必须用户登录以后,才可以访问。
/loginlogin.html登录页面,用户名密码输入正确,自动跳转到home.html。
/logout退出登录后,自动跳转到index.html。
打开app.js文件,增加路由配置:

app.use('/', routes);
app.use('/users', users);
app.use('/login', routes);
app.use('/logout', routes);
app.use('/home', routes);


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

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});

router.route('/login')
.get(function(req, res) {
res.render('login', { title: '用户登录' });
})
.post(function(req, res) {
var user={
username: 'admin',
password: '123456'
}
if(req.body.username === user.username && req.body.password === user.password){
res.redirect('/home');
}
res.redirect('/login');
});

router.get('/logout', function(req, res) {
res.redirect('/');
});

router.get('/home', function(req, res) {
var user={
username:'admin',
password:'123456'
}
res.render('home', { title: 'Home', user: user });
});

module.exports = router;


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

login.html

<% include header.html %>
<div class="container">
<form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post">
<fieldset>
<legend>用户登录</legend>
<div class="form-group">
<label class="col-sm-3 control-label" for="username">用户名</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="username" name="username" placeholder="用户名" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="password">密码</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="password" name="password" placeholder="密码" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary">登录</button>
</div>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>


home.html

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


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

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


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

session

安装中间件

npm install express-session


npm install connect-mongodb


npm install mongodb


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

settings.js

module.exports = {
COOKIE_SECRET: 'ywang1724.com',
URL: 'mongodb://127.0.0.1:27017/nodedb',
DB: 'nodedb',
HOST: '127.0.0.1',
PORT: 27017,
USERNAME: 'admin',
PASSWORD: '123456'
};


msession.js

var Settings = require('./settings');
var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
var db = new Db(Settings.DB, new Server(Settings.HOST, Settings.PORT, {auto_reconnect:true, native_parser: true}),{safe: false});

module.exports = db;


修改app.js文件:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//采用connect-mongodb中间件作为Session存储
var session = require('express-session');
var Settings = require('./database/settings');
var MongoStore = require('connect-mongodb');
var db = require('./database/msession');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

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

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
//session配置
app.use(session({
cookie: { maxAge: 600000 },
secret: Settings.COOKIE_SECRET,
store: new MongoStore({
username: Settings.USERNAME,
password: Settings.PASSWORD,
url: Settings.URL,
db: db})
}))
app.use(function(req, res, next){
res.locals.user = req.session.user;
next();
});

app.use(express.static(path.join(__dirname, 'public')));

......


修改index.js文件:

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});

router.route('/login')
.get(function(req, res) {
res.render('login', { title: '用户登录' });
})
.post(function(req, res) {
var user = {
username: 'admin',
password: '123456'
}
if(req.body.username === user.username && req.body.password === user.password){
req.session.user = user;
res.redirect('/home');
} else {
res.redirect('/login');
}
});

router.get('/logout', function(req, res) {
req.session.user = null;
res.redirect('/');
});

router.get('/home', function(req, res) {
res.render('home', { title: 'Home' });
});
module.exports = router;


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

页面访问控制及提示

访问控制设计:

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

router.get('/home', function(req, res) {
authentication(req, res);
res.render('home', { title: 'Home' });
});

function authentication(req, res) {
if (!req.session.user) {
return res.redirect('/login');
}
}


重启服务,访问成功。

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

app.use(function(req, res, next) {
res.locals.user = req.session.user;
var err = req.session.error;
delete req.session.error;
res.locals.message = '';
if (err) {
res.locals.message = '<div class="alert alert-warning">' + err + '</div>';
}
next();
});


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

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});

router.route('/login')
.get(function(req, res) {
if (req.session.user) {
res.redirect('/home');
}
res.render('login', { title: '用户登录' });
})
.post(function(req, res) {
var user = {
username: 'admin',
password: '123456'
}
if (req.body.username === user.username && req.body.password === user.password) {
req.session.user = user;
res.redirect('/home');
} else {
req.session.error='用户名或密码不正确';
res.redirect('/login');
}
});

router.get('/logout', function(req, res) {
req.session.user = null;
res.redirect('/');
});

router.get('/home', function(req, res) {
authentication(req, res);
res.render('home', { title: 'Home' });
});

function authentication(req, res) {
if (!req.session.user) {
req.session.error='请先登录';
return res.redirect('/login');
}
}
module.exports = router;


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

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


重启服务,访问成功。输入错误用户名密码:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  express-验证