Nodejs 在Express 使用session 做登录控制

Nodejs 在Express 使用session 做登录控制

var filter = require(’./lib/filter’);

filter中判断是否已经登录如果登录了则过去,否则跳转到登录页

exports.authorize = function(req, res, next) {
  if (!req.session.user_id) {
    res.redirect('/admin/login');
  } else {
    next();
  }
}

在configure中使用session

app.use(express.cookieParser('sctalk admin manager'));
app.use(express.session());

路由控制,在需要登录验证的路由上加上filter.authorize

app.get('/admin/login',admin.login);
app.get('/admin/logout',admin.logout);

app.get('/admin/:action',filter.authorize, function(req, res, next){
    if(admin[req.params.action])
    {
      admin[req.params.action](req, res, next);
    }
    else
    {
      res.status(404);
      res.end();
    }
});

最后在登录判断时候添加session即可

exports.dologin = function(req, res,next){
    // 校验
    req.assert('username', "用户名不能为空").notEmpty();
    req.assert('password', "密码不能为空").notEmpty();
    var errors = req.validationErrors();
    if(errors && errors.length>0)
    {
      var ermsg = [];
      for(var i=0;i<errors.length;i++)
      {
        ermsg.push(errors[i].msg);
      }
      var json={title:'管理后台-- 请先登录',error:ermsg.join("\n")};
      res.render('admin/login', json);
      return;
    }
    var userid = req.body.username;
    var pwd = req.body.password;
    var ip = req.ip;
    userbiz.checkUser(userid,pwd,ip,function(err,user){
      if(!!err){
        var json={title:'管理后台-- 请先登录',error:err};
        res.render('admin/login', json);
      }
      else{
        req.session.user_id = user.user_id;
        req.session.user = user;
        res.redirect("/admin/index");
      }
     
    });
   
};

8 回复

Node.js 在 Express 中使用 Session 做登录控制

在本教程中,我们将展示如何在 Express 应用程序中使用 Session 进行登录控制。我们将创建一个简单的管理后台,用户必须登录才能访问某些页面。

1. 安装依赖包

首先确保你已经安装了 Express 和相关中间件:

npm install express express-session body-parser ejs

2. 创建过滤器文件 filter.js

在项目目录中创建一个名为 filter.js 的文件,并编写以下代码:

// filter.js
exports.authorize = function(req, res, next) {
  if (!req.session.user_id) {
    res.redirect('/admin/login');
  } else {
    next();
  }
}

3. 配置 Express 应用程序

在你的主应用程序文件(如 app.jsindex.js)中配置 Express 并启用 Session:

// app.js
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(session({
  secret: 'sctalk admin manager',
  resave: false,
  saveUninitialized: true
}));

const filter = require('./lib/filter');
const admin = require('./routes/admin'); // 假设你的路由文件在这里

// 路由定义
app.get('/admin/login', admin.login);
app.get('/admin/logout', admin.logout);

app.get('/admin/:action', filter.authorize, function(req, res, next) {
  if (admin[req.params.action]) {
    admin[req.params.action](req, res, next);
  } else {
    res.status(404);
    res.end();
  }
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

4. 实现登录逻辑

admin.js 文件中实现登录、登出和验证逻辑:

// routes/admin.js
const bcrypt = require('bcrypt');
const userBiz = require('../business/userBiz');

exports.login = function(req, res) {
  res.render('admin/login');
};

exports.dologin = function(req, res) {
  req.assert('username', "用户名不能为空").notEmpty();
  req.assert('password', "密码不能为空").notEmpty();
  
  const errors = req.validationErrors();
  if (errors && errors.length > 0) {
    const errorMessages = errors.map(error => error.msg).join('\n');
    res.render('admin/login', { title: '管理后台-- 请先登录', error: errorMessages });
    return;
  }

  const { username, password } = req.body;
  userBiz.checkUser(username, password, req.ip, (err, user) => {
    if (err) {
      res.render('admin/login', { title: '管理后台-- 请先登录', error: err });
    } else {
      req.session.user_id = user.user_id;
      req.session.user = user;
      res.redirect('/admin/index');
    }
  });
};

exports.logout = function(req, res) {
  req.session.destroy((err) => {
    if (err) {
      console.error('Session destroy failed:', err);
    }
    res.redirect('/admin/login');
  });
};

5. 用户业务逻辑(简化版)

假设有一个用户业务逻辑模块 userBiz.js,用于验证用户身份:

// business/userBiz.js
module.exports.checkUser = function(username, password, ip, callback) {
  // 这里只是一个示例,实际应用中应该从数据库查询用户信息并验证密码
  if (username === 'admin' && password === '123456') {
    const user = {
      user_id: 1,
      username: 'admin'
    };
    callback(null, user);
  } else {
    callback('用户名或密码错误');
  }
};

通过以上步骤,你就可以实现一个基本的基于 Session 的登录控制功能。当用户尝试访问受保护的路由时,会检查是否已登录。如果没有登录,则会被重定向到登录页面。


怎么没有logout呢?

学习

express 4.x不适用了,d:(

没用过express 也没研究过他的那些中间件, 只是想问下express 的 session 是保存在内存中每次请求来去根据sessionID去取数据的么

不灌水会死么楼主,换个头像我就不认识你了?

要实现基于 express-session 的登录控制,你需要确保在 Express 应用中正确配置和使用 session 中间件,并编写相应的过滤器来检查用户是否已登录。下面是完整的代码示例:

1. 安装依赖

首先,确保你安装了必要的依赖项:

npm install express express-session body-parser

2. 配置 session 和路由

server.js

const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');

const app = express();

// 设置中间件
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
  secret: 'sctalk admin manager',
  resave: false,
  saveUninitialized: true
}));

// 路由
const adminRoutes = require('./routes/admin'); // 假设你的路由文件位于 routes/admin.js
app.use('/admin', adminRoutes);

// 登录路由
app.post('/admin/dologin', adminRoutes.dologin); // 处理登录逻辑

// 启动服务器
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

3. 编写过滤器和路由

routes/admin.js

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

// 过滤器
router.use((req, res, next) => {
  if (!req.session.user_id) {
    res.redirect('/admin/login');
  } else {
    next();
  }
});

// 路由
router.get('/login', (req, res) => {
  res.send('<form method="POST" action="/admin/dologin">\
              <input type="text" name="username" placeholder="Username">\
              <input type="password" name="password" placeholder="Password">\
              <button type="submit">Login</button>\
            </form>');
});

router.post('/dologin', (req, res, next) => {
  // 校验
  req.assert('username', "用户名不能为空").notEmpty();
  req.assert('password', "密码不能为空").notEmpty();
  const errors = req.validationErrors();
  if (errors && errors.length > 0) {
    const errorMessages = errors.map(e => e.msg).join('\n');
    return res.render('admin/login', { title: '管理后台-- 请先登录', error: errorMessages });
  }

  // 模拟用户验证
  const username = req.body.username;
  const password = req.body.password;

  if (username === 'admin' && password === '123456') {
    req.session.user_id = 1;
    req.session.user = { user_id: 1, username: 'admin' };
    res.redirect('/admin/index');
  } else {
    res.render('admin/login', { title: '管理后台-- 请先登录', error: '用户名或密码错误' });
  }
});

router.get('/index', (req, res) => {
  res.send(`Welcome, ${req.session.user.username}`);
});

module.exports = router;

4. 解释

  • session 中间件: 使用 express-session 来管理 session。
  • 过滤器: 在路由之前检查 req.session.user_id 是否存在,如果不存在则重定向到登录页面。
  • 登录处理: 当用户提交登录表单时,验证用户名和密码,如果验证通过,则将用户信息存储在 session 中,并重定向到受保护的页面。

这样,你就实现了基于 express-session 的登录控制。

回到顶部