Nodejs中session的简单使用及通过session实现身份验证的方法

一、什么是session

session,即会话,在Node.js中属于Web应用的内部机制,它记录了用户在应用程序中的会话状态。服务器在给客户端返回响应时,会随之返回一个sessionID,该ID会在客户端被记录下来。客户端之后每次访问服务器时,都会携带着这个sessionID一同发送给服务器,以识别当前访问者的身份。

二、Nodejs中session的简单使用

  1. 安装express-session

使用express-session中间件实现session机制需要先安装express-session模块,用npm命令直接安装即可

npm install express-session
  1. 在app.js中使用express-session中间件

在需要使用session的应用程序中引入express-session中间件

const session = require('express-session');
const app = express();

确保该中间件在路由中间件之前加载,并将其挂载到app对象上

app.use(session({
  secret: 'mysession',        // session的签名(加密)字符串,用于防止篡改cookie
  resave: false,             // 每次请求是否重新生成sessionID
  saveUninitialized: true,   // 保存未初始化的session
  cookie: { maxAge: 1000 * 60 * 60 * 24 }   // session会话物理存储时间
}));

以上配置了一些session中间件的初始化参数,如签名字符串secret用于防止篡改cookie,resave设置为false表示每次请求是否重新生成sessionID,saveUninitialized设置为true表示保存未初始化的session,cookie对象配置表示session会话物理存储时间为一天

  1. 使用session

使用req.session访问session,具体实验见下

app.get('/session-test', (req, res) => {
  if (req.session.isVisit) {
    req.session.isVisit++;
    res.send(`<p>第${req.session.isVisit}次来此页面</p>`);
  } else {
    req.session.isVisit = 1;
    res.send('欢迎第一次来此页面');
  }
});

以上代码编写了一个简单的路由,请求该路由时如果是第一次来访问,就缓存一个isVisit值为1,表示第一次访问。若是第二次及以上的访问,就做求HTTP请求并将之前的isVisit值+1,表示是第几次访问。

  1. 销毁session

使用req.session.destory()方法可以立即注销掉该用户的session

app.get('/session-destroy', (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      console.log(err);
    } else {
      console.log(`session destroyed`);
      res.send(`session destroyed`);
    }
  });
});

以上代码实现了一个路由,请求该路由时可以立即销毁用户的session,并在后端记录一条“session destroyed”的日志

三、利用session实现身份验证

session机制是构建Web应用的一项重要的内部机制,它为构建身份验证所需的数据扮演着重要角色。利用session进行身份验证,主要包括以下步骤:

  1. 登录

当用户输入合法的登录信息,服务器端会验证用户身份,并如果成功登录,则在session中缓存用户登录状态。

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username && password) {
    // 检验没有问题,修改session中isLogin状态
    req.session.isLogin = true;
    req.session.username = username;
    res.redirect('/');
  } else {
    res.redirect('/login');
  }
})
  1. 访问受限资源

在需要进行身份验证的路由中,首先需要加入身份验证中间件,对用户是否合法进行验证。代码实现如下:

const auth = (req, res, next) => {
  if(req.session.isLogin) {
    next();
  }else {
    res.redirect('/login');
  }
}
  1. 登出

登出操作其实就是删除session中缓存的登录状态。代码如下:

app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
    if(err) throw err;
  })
  res.redirect('/');
})

四、示例

  1. 简单的登录验证

这个示例是一个临时存放的登录验证页面,它的主要功能是验证用户名和密码是否正确,正确后才能进入受限制的页面。代码如下

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

const app = express();
app.use(bodyParser.urlencoded({extended: true}));

// 使用session中间件
app.use(session({
  secret: 'mysession',               
  resave: false,             
  saveUninitialized: true,   
  cookie: { maxAge: 1000*60*60*24 } // session会话使用的时间
}));


// 页面路由 
app.get('/login', (req, res) => {
  res.send(`
    <h1>登录页面</h1>
    <form method='post' action='/login'>
      <p><input name='username' placeholder='用户名'></p>
      <p><input name='password' placeholder='密码'></p>
      <p><button type='submit'>登录</button></p>
    </form>
  `)
})

app.post('/login', (req, res) => {
  const {username, password} = req.body;
  if (username && password) {
    if (username === 'admin' && password === '123456') {
      req.session.isLogin = true;
      res.redirect('/');
    } else {
      res.send(`用户名或密码错误`);
    }
  } else {
    res.send(`用户名或密码不能为空`);
  }
})

app.get('/', (req, res) => {
  if (req.session.isLogin) {
    res.send(`
      <h1>欢迎来到首页</h1>
      <a href='/restricted-view'>进入受限制的页面</a>
      <a href='/logout'>退出登录</a>
    `);
  } else {
    res.send(`
      <h1>您尚未登录</h1>
      <a href='/login'>进入登录页面</a>
    `);
  }
})

const auth = (req, res, next) => {
  if(req.session.isLogin) {
    next();
  }else {
    res.redirect('/login');
  }
}

app.get('/restricted-view', auth, (req, res) => {
  res.send(`
    <h2>您已登录,可以允许查看此页面</h2>
    <a href='/'>返回首页</a>
  `);
})

app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
    if(err) throw err;
  })
  res.redirect('/');
})

app.listen(3000, (err) => {
  if (err) throw err;
  console.log(`server is listening on port 3000`);
})
  1. 在Express+MongoDB中使用session进行身份验证

这个示例是一个使用Express+MongoDB来创建的Node.js应用,它使用session机制来进行身份验证。代码实现如下:

/* Dependencies loading*/
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const mongoose = require('mongoose');

/* Configuring server and database */
const app = express();
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/db_name', {useNewUrlParser: true, useUnifiedTopology: true}).then(() => {
  console.log('connection to database successful');
}).catch((err) => {
  console.log(`error occurred with message ${err}`);
})

/* Adding middlewares */
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({secret: 'mysession', resave: false, saveUninitialized: true, cookie: { maxAge: 1000*60*60*24 }}));
app.use(express.static(__dirname + '/public/'));

/* Defining Models */
const User = mongoose.model('User', {
  username: {
    type: String,
    required: true,
    trim: true,
    unique: true
  },
  password: {
    type: String,
    required: true,
    trim: true
  }
});

/* Routers*/
app.post('/login', (req, res) => {
  const {username, password} = req.body;
  if (username && password) {
    User.findOne({username, password}).exec((err, user) => {
      if (err) {
        res.send(`login error with message ${err}`);
      } else if (user) {
        req.session.isLogin = true;
        req.session.username = username;
        req.session.userId = user._id.toString();
        res.redirect('/restricted-view');
      } else {
        res.send(`username or password incorrect`);
      }
    })
  } else {
    res.send(`username or password can not be empty`);
  }
})

const auth = (req, res, next) => {
  if(req.session.isLogin) {
    next();
  }else {
    res.redirect('/login');
  }
}

app.get('/restricted-view', auth, (req, res) => {
  res.sendFile(path.join(__dirname, './public/restricted-view.html'));
})

app.get('/', (req, res) => {
  if(req.session.isLogin) {
    res.sendFile(path.join(__dirname, './public/index-logged-in.html'));
  } else {
    res.sendFile(path.join(__dirname, './public/index-not-logged-in.html'));
  }
})

/* starting app */
app.listen(3000, (err) => {
  if (err) throw err;
  console.log(`server is listening on port 3000`);
})

以上示例中,在/login路由处,如果输入的用户名和密码都正确,则会在session中缓存用户的登录状态、用户名和用户ID。在受限制的视图页中,如果用户访问当前页面以前并没有登录(即session中没有记录用户登录状态),就会被重定向到登录页面,被告知需要登录才能访问受限制视图。如果用户已经登录过,就会加载视图并在视图中显示出用户ID、用户名等内容。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Nodejs中session的简单使用及通过session实现身份验证的方法 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 用Nginx反向代理Node.js的方法

    使用Nginx反向代理Node.js是一种常见的解决方案,可以提高网站的性能和可靠性,同时保护应用程序免受攻击。以下是使用Nginx反向代理Node.js的完整攻略: 1. 安装和配置Node.js应用程序 第一步是安装和配置Node.js应用程序。这里以Express框架为例进行说明: 步骤一:安装Node.js 可以从Node.js官网下载最新版本的No…

    node js 2023年6月8日
    00
  • node.js中的console.warn方法使用说明

    当开发者在使用Node.js编写应用程序时,经常需要在代码中打印输出调试信息。Node.js提供了console模块来处理输出,其中console.warn()方法可以用于在控制台输出警告信息。 1. 使用说明 1.1 语法 console.warn([data][, …args]) 1.2 参数 data:警告信息,可以是字符串,也可以是任意JavaS…

    node js 2023年6月8日
    00
  • node.js中的fs.rmdir方法使用说明

    下面是详细讲解“node.js中的fs.rmdir方法使用说明”的完整攻略。 一、什么是fs.rmdir方法? fs.rmdir()是Node.js中一个用于删除目录的内置方法。它可以删除空目录,并且不递归删除子目录。 二、fs.rmdir方法的语法 fs.rmdir()方法使用如下: fs.rmdir(path, callback) 其中: path:表示…

    node js 2023年6月8日
    00
  • Node.js API详解之 repl模块用法实例分析

    下面我将为您详细解释“Node.js API详解之 repl模块用法实例分析”的完整攻略。 什么是 repl 模块? repl 模块是 Node.js 内置模块之一,它提供了一种类似交互式解释器的环境,可以让开发者在命令行中直接使用 JavaScript 代码来进行测试、调试以及一些其它方便的操作。 repl 模块的核心方法和属性 repl 模块主要有以下核…

    node js 2023年6月8日
    00
  • node安装–linux下的快速安装教程

    下面我将详细讲解“node安装–linux下的快速安装教程”的完整攻略。 1. 安装nodeJS 在Linux系统下,安装NodeJS需要进行以下步骤: 1.1 添加NodeJS官方源 在终端中执行以下命令: curl -sLhttps://deb.nodesource.com/setup_14.x | sudo -E bash – 1.2 安装NodeJ…

    node js 2023年6月8日
    00
  • package.json与package-lock.json的区别及详细解释

    当开发者使用npm进行包含包的管理时,会有两个文件被生成: package.json和package-lock.json。这两个文件都用来描述项目中使用到的依赖库以及版本号等信息。但是,在实际开发中,它们所起到的作用却是有所区别的。 package.json的作用 package.json是一个标准的JSON格式的文件,它主要用于定义项目中所需的依赖库以及版…

    node js 2023年6月8日
    00
  • zTree 树插件实现全国五级地区点击后加载的示例

    下面我来详细讲解一下“zTree 树插件实现全国五级地区点击后加载的示例”的完整攻略。 1. 安装 zTree 插件 要实现该示例,首先需要安装 zTree 插件。可以在 zTree 的官网上下载最新的版本,也可以直接引用在线的CDN资源。这里我以引用在线CDN资源的方式来进行示例说明。 <!– 引入 zTree 树插件的 css 文件 –>…

    node js 2023年6月8日
    00
  • node.js如何自定义实现一个EventEmitter

    要自定义实现一个EventEmitter,需要使用Node.js内置的Event模块来进行操作。下面是具体的实现步骤: 步骤一:创建EventEmitter类 首先,我们需要创建一个EventEmitter类。可以通过类的prototype属性将emit(触发事件)、on(注册监听器)和removeListener(移除监听器)函数添加进EventEmitt…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部