一、需求

基于中间件对用户的登录状态进行鉴别,如果用户未登录,则跳转到登录界面。

用户的登录状态基于 session 存储:

  • req.session.logined: Boolean,用户是否登录
  • req.session.loginUser: Object,已经登录用户的信息

二、基本信息

项目没有使用脚手架进行安装,只是阐述一下验证的基本逻辑,因此也没有写页面。

项目的目录信息:

1.jpg

  • middlewares:所有的中间件存放位置(log是用来记录访问历史的中间件)
  • routes:所有的路由文件的存放位置
  • app.js:主文件

主要的实现流程:

在访问需要确定是否登录的路由时,比如 /index 下的所有路由,使用中间件检查登录状态,如果没有登录,则跳转,如果登录则 next()

/sign 下的所有路由(如登录 get、登录 post、退出登录:all、注册 get、注册 post) 这些都不需要判断登录状态,则单独编组,并且不 use 中间件即可。

 三、实现:

1)express 中使用 session

要在 express 中使用 session,需要安装 cookie-parserexpress-session,(脚手架默认是安装了 cookie-parser

yarn add cookie-parser express-session

在 app.js 中使用 session 和 cookie:

下面是我完整的 app.js 文件,除了对 cookie 和 session 的引用之外,路由我是直接通过 routes 中写入的,并且是导入进行 use 的。而为了方式出现 /sign/in 这样的路由也匹配到 / 这个路由,我直接将 / 跳转到了 /index

  • 文件名:app.js
const express = require('express');
const session = require('express-session');
const cookieParser = require('cookie-parser');

const app = express();

app.use(cookieParser());
app.use(session({
    secret: '12345',
    name: 'testapp',  
    cookie: {maxAge: 80000 },  
    resave: false,
    saveUninitialized: true,
}));

app.get('/',(req,res)=>{
  return res.redirect('/index');
});

app.use('/index',indexRoutes);
app.use('/sign',signRoutes);

app.listen(3000);

2)路由文件

  • 文件名:routes/index.js

这个文件中,引入了 checkLogin 这个 middleware,并在路由中使用了这个 middleware。

const express = require("express");
const logMiddleware = require('../middlewares/log');
const checkLogin  = require('../middlewares/checklogin');
const router = express.Router();

router.use(logMiddleware);
router.use(checkLogin);


router.get('/',(req,res)=>{
  res.send("1");
});

module.exports = router;
  • 文件名:routes/sign.js

这个很简单就是给了一个 get 的路由而已,不需要使用 checkLogin middleware。

const express = require("express");
const logMiddleware = require('../middlewares/log');
const router = express.Router();

router.use(logMiddleware);


router.get('/in',(req,res)=>{
  res.send("Login Page");
});

module.exports = router;

3)中间件文件

  • 文件名:middlewares/checklogin.js

这个文件很简单,就是检查 session 是否登录,如果登录则 next(),如果没有则进行 redirect('/sign/in) 即可。

/**
 * @name checklogin
 * @description 检查用户是否登录的中间件
 * @author postbird
 */

 module.exports = (req,res,next)=>{
   if(!req.session.logined || !req.session.loginUser){
     return res.redirect('/sign/in');
   }
   next();
 }