node.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > node.js > Express拦截器功能

Express框架实现简单拦截器功能示例

作者:Teacher_Tian_2019

这篇文章主要介绍了Express框架实现简单拦截器功能,结合实例形式分析了express框架拦截器相关功能与使用方法,需要的朋友可以参考下

1、前言

  在前文express框架+bootstrap美化ejs模板提到,考试成绩属于非公开的数据。需要根据浏览器端访问的用户的身份进行判断,如果是有权限的用户才会返回相应的数据。这种功能就是本节我要说明的“拦截器”。

2、分析

  首先,要完成拦截器的功能,需要有session的支持,我们需要下载express-session模块:

npm install --save express-session

3、开发过程

3.1、引入express-session模块

  在入口脚本app.js中,引入express-session模块:

var session = require("express-session");

3.2、完成session配置

  在入口脚本app.js中,设置session到app上,完成session的配置:

// 设置session中间件
app.use(session({
  secret: 'keyboard cat',
  resave: false,              //强制保存 session 即使它并没有变化,。默认为 true。建议设置成 false
  saveUninitialized: true,
  cookie: {
    // secure: true,
    maxAge:2*60*60*1000                 /*过期时间*/
  },
  rolling:true                //在每次请求时重新设置 cookie,用于重置 cookie 过期时间(默认:false)
}))

3.3、拦截器代码编写

  因为app.js是站点访问的入口文件,所以为了尽可能的拦截所有的web请求,拦截器需要写在所有的app.use(准确地说,是所有的路由)前。下面是从app.js中截取出来的代码片断:

//添加拦截器
app.use(function (req, res, next) {
  if(req.session.user){
    //已经登录过的用户(存在session)
    console.log("这个用户已经登陆:" + req.session.user.u_name);
    next();
  }else{
    //用户没有登录(session)前
    var arr = req.url.split('/');
    //去除get请求携带的参数
    for (var i = 0; i < arr.length; i++) {
        arr[i] = arr[i].split('?')[0];
    }
    //罗列所有无需权限检查的路由
    if (arr[1] === 'login' || arr[1] === 'logout' || arr[1] === '') {
      next();
    } else {
      //最初请求的链接也做为参数传递给login页面
      res.redirect('/login' + req.url);  // 将用户重定向到登录页面
      res.end();
    }
  }
});
/* 尽可能让拦截器在所有路由的前边 */
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
/* 略 */

3.4、登录功能开发

  在app.js上方,先引入一个路由文件,它可以为我们提供登录的get和post请求处理;

var loginRouter = require('./routes/login');

  在app.js文件中,将loginRouter绑定到/login这个路径上:
在这里插入图片描述
  像上边这样,app.js的改造就完成了。接下来看一看./routes/login.js的代码吧:

var express = require('express');
var router = express.Router();
/* GET login */
router.get('/', function(req, res, next) {
  if(req.session.user){
    res.redirect("/");  // 将用户重定向到登录页面
    res.end();
  }else{
    res.render('login', {redirect_path:""});
  }
});
router.get('/:redirect_path', function(req, res, next) {
  var redirect_path = req.params.redirect_path || "/";
  if(req.session.user){
    res.redirect("/" + redirect_path);  // 将用户重定向到登录页面
    res.end();
  }else{
    res.render('login', {redirect_path});
  }
});
/* POST login */
router.post('/', function(req, res, next) {
  var {u_name,u_password,redirect_path} = req.body;
  var user = {u_name,u_password};
  //密码校验
  //仅仅是个模板,省略了从数据库查询的过程
  if((u_name == "张三" || u_name == "李四") && u_password == "123456"){
    //写入session
    // req.session.user = {u_name,u_password};
    req.session.regenerate(() => {
      req.session.user = user;
      req.session.success = "Authenticated as " + user.u_name;
      res.redirect("/" + redirect_path);  // 将用户重定向到登录页面
      res.end();
    });
  }else{
    //认证失败
    res.redirect('/login' + req.url);  // 将用户重定向到登录页面
    res.end();
  }
});
module.exports = router;

  在./routes/login.js中提及了login.ejs模板,代码如下:

<!DOCTYPE html>
<html>
  <head>
    <title>Login</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <form action="/login" method="POST">
      <div>
        <input type="hidden" name="redirect_path" value = "<%=redirect_path%>">
      </div>
      <div>
          用户名:<input type="text" name="u_name" />
      </div>
      <div>
          密码:<input type="password" name="u_password" />
      </div>
      <div>
        <input type="submit" value="登录">
      </div>
    </form>
  </body>
</html>

  同时,我在这里把score.ejs模板的代码也贴出来(为本次演示功能的开发做了一些调整):

<!DOCTYPE html>
<html>
  <head>
    <title>成绩单</title>
    <!-- 引入bootstrap样式文件 注意这里的href是相对于public目录的 -->
    <link rel="stylesheet" href="/stylesheets/bootstrap.min.css" rel="external nofollow" >
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <div><%= year %>年高考成绩查询(<%= u_name%>)</div>
    <table>
        <% scores.forEach(function(item,index){ %>
            <tr><td><%= index + 1 %></td><td><%=item.course %></td><td><%=item.score %></td></tr>
        <% }); %>
    </table>
  </body>
</html>

4、验证

  完成以上主要步骤之后,可以启动网站试试了!
初次访问一下http://localhost:3000/system,结果是下边这样的:
在这里插入图片描述
  有没有发现,页面重定向到了登录页面,此时链接也变成了localhost:3000/login/system,其实system是一个路由参数(用于告诉服务器,在登录成功之后重定向的位置)。填写账号/密码信息:李四/123456后,效果如下:
在这里插入图片描述
  再进一步验证一下,把浏览器关闭,确保已经与服务器断开了链接,重新访问主页,按照login.js中的拦截规则,主页/是不被拦截的。
在这里插入图片描述
   果真如此。

4、写在最后

  整理到这里就结束了,虽然描述得不是很细致,但在以上章节的代码中,我想信你可能能体会到拦截器的用途;并可以参照案例的代码完成你的练习。
  最近,在某项目实践的过程中,发现lowdb这种非常轻便小巧的数据库,我也成功地在express项目中完成了CRUD等基本功能。那一下节,我就介绍一下这个数据库,并讲一讲如何在express项目中使用lowdb数据库完成基本的CRUD操作吧。

您可能感兴趣的文章:
阅读全文