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

来源:互联网 发布:清华经管北大光华知乎 编辑:程序博客网 时间:2024/05/28 20:19

声明: 本文不是原创,作者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/wwwE:\project>

根据提示下载依赖包:

E:\project> cd .\nodejs-demoE:\project\nodejs-demo> npm installnpm WARN deprecated static-favicon@1.0.2: use serve-favicon modulestatic-favicon@1.0.2 node_modules\static-favicondebug@0.7.4 node_modules\debugejs@0.8.8 node_modules\ejscookie-parser@1.0.1 node_modules\cookie-parser├── cookie-signature@1.0.3└── cookie@0.1.0morgan@1.0.1 node_modules\morgan└── bytes@0.3.0body-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 setupapp.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 handlerapp.use(function(req, res, next) {    var err = new Error('Not Found');    err.status = 404;   next(err);});/// error handlers// development error handler// will print stacktraceif (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 userapp.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 setupapp.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 bootstrapbootstrap@3.2.0 node_modules\bootstrapE:\project\nodejs-demo> npm install jqueryjquery@2.1.1 node_modules\jqueryE:\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 不需要登录,可以直接访问。 /home home.html 必须用户登录以后,才可以访问。 /login login.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 setupapp.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">

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

1 0
原创粉丝点击