Nodejs进阶:express+session实现简易登录身份认证

下面我将为你详细讲解“Nodejs进阶:express+session实现简易登录身份认证”的完整攻略。本攻略主要分为以下几个部分:

  1. 什么是session
  2. express-session的使用
  3. 实现简易登录身份认证的步骤
  4. 示例说明

什么是session

在Web开发中,我们常常需要通过用户的身份认证来实现一些特殊的操作。而在HTTP的无状态协议中,为了保存用户的认证状态,我们通常需要使用session来存储用户的登录信息。session是一种服务端技术,用于存储用户的会话信息,比如登录状态、购物车内容等。在用户访问网站时,服务端会生成一个session ID并将其返回给客户端,以便在后续的请求中识别出该用户的身份。

express-session的使用

在使用express-session之前,我们需要先安装并引入该模块:

npm install express-session --save
const session = require('express-session');

使用express-session非常简单,只需要在express中使用app.use(session(options))即可。其中,options是一个可配置的选项对象,用于设置session的相关参数。常见的options参数如下:

  • secret:用于配置加密session ID的秘钥,该秘钥不应该泄露给客户端,一般应该存储在服务端。例如:
app.use(session({ secret: 'keyboard cat' }));
  • resave:当用户请求结束时,是否保存session的修改。如果设为true,则每次请求都会保存session的变化,不管需不需要。例如:
app.use(session({ resave: true }));
  • saveUninitialized:当用户请求中未包含session ID时,是否创建新的session。如果设为true,则每次请求都会创建新的session。例如:
app.use(session({ saveUninitialized: true }));
  • cookie:用于设置session的cookie选项,例如过期时间、路径、域名等。例如:
app.use(session({ cookie: { maxAge: 60000 }}));
  • store:用于设置session的存储方式,常见的有Memory、Redis和MongoDB等。例如:
const MongoStore = require('connect-mongo')(session);
app.use(session({
  secret: 'keyboard cat',
  store: new MongoStore({ url: 'mongodb://localhost/test-app' })
}));

实现简易登录身份认证的步骤

实现简单的登录身份认证通常分为以下几个步骤:

  1. 准备用户登录表单,表单中需要包含用户名和密码两个输入框,并设置提交按钮的action为提交登录请求的路由。

  2. 编写登录请求路由,接收用户提交的用户名和密码,验证该用户是否合法,如果合法则使用express-session设置session信息,并重定向到用户首页;否则返回登录失败的提示信息。

  3. 用户访问其他页面时,使用express-session验证用户的身份是否已经通过认证,如果认证成功则显示该页面;否则重定向到用户登录页面。

下面我们通过一个完整的示例来演示上述步骤的实现:

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

// 设置session加密秘钥
app.use(session({ secret: 'keyboard cat' }));

// 用户登录页面
app.get('/', (req, res) => {
  res.send(`
    <h1>Login</h1>
    <form method="POST" action="/login">
      <input type="text" name="username" placeholder="Username" required><br>
      <input type="password" name="password" placeholder="Password" required><br>
      <button type="submit">Submit</button>
    </form>
  `);
});

// 处理用户登录请求
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  // 模拟用户信息验证
  if (username === 'admin' && password === '123456') {
    // 设置session信息
    req.session.user = { username };
    // 重定向到用户页面
    res.redirect('/home');
  } else {
    // 登录失败
    res.send('Login failed');
  }
});

// 用户首页
app.get('/home', (req, res) => {
  // 验证session信息
  if(req.session.user) {
    res.send(`<h1>Welcome, ${req.session.user.username}</h1>`);
  } else {
    // 重定向到登录页面
    res.redirect('/');
  }
});

// 启动应用
app.listen(3000, () => {
  console.log('App is running at http://localhost:3000');
});

在上述示例中,我们使用了express-session模块来设置session信息,包括用户登录和已登录状态的验证。表单的提交通过POST请求方式来处理,在处理该请求时,我们使用req.body来获取用户提交的登录信息,并进行了简单的合法性验证。如果验证通过,则设置session信息,然后重定向到用户首页。如果验证不通过,则返回登录失败的提示信息。在用户访问其他页面时,我们使用req.session来验证session信息是否存在,如果存在,则显示该页面的内容,否则重定向到用户登录页面。

示例说明

下面是两种使用express-session的示例场景:

示例1:购物车功能

在购物网站中,用户可以添加商品到购物车中,但是当用户关闭了网页后,购物车的内容会被清空。为了保存用户购物车的信息,我们可以使用session来存储购物车的内容,并在用户再次访问网站时恢复该购物车的内容。具体实现方法类似于示例中用户登录功能的处理方式。

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

// 设置session加密秘钥
app.use(session({ secret: 'keyboard cat' }));

// 商品列表页面
app.get('/products', (req, res) => {
  res.send(`
    <h1>Product List</h1>
    <ul>
      <li>Product A <a href="/add-to-cart?a=1">Add to cart</a></li>
      <li>Product B <a href="/add-to-cart?a=2">Add to cart</a></li>
      <li>Product C <a href="/add-to-cart?a=3">Add to cart</a></li>
    </ul>
  `);
});

// 加入购物车请求路由
app.get('/add-to-cart', (req, res) => {
  const { a } = req.query;
  // 判断购物车是否已经存在
  if(req.session.cart) {
    // 如果已经存在,则加入新的商品
    req.session.cart.push(a);
  } else {
    // 如果不存在,则初始化购物车内容
    req.session.cart = [a];
  }
  res.send('Success');
});

// 购物车页面
app.get('/cart', (req, res) => {
  // 如果购物车存在,则显示购物车内容
  if(req.session.cart) {
    const products = ['Product A', 'Product B', 'Product C'];
    const items = req.session.cart.map(a => `<li>${products[a-1]}</li>`);
    res.send(`
      <h1>My Shopping Cart</h1>
      <ul>
        ${items.join('')}
      </ul>
    `);
  } else {
    res.send('<h1>Your shopping cart is empty</h1>');
  }
});

// 启动应用
app.listen(3000, () => {
  console.log('App is running at http://localhost:3000');
});

在上述示例中,我们使用session来存储购物车的内容,并在加入购物车和显示购物车的请求中读取session中的信息。在加入购物车时,我们先检查购物车是否已经存在,如果存在,则将新商品加入购物车,否则初始化购物车的内容。在显示购物车时,我们通过session中的购物车内容来生成商品列表,然后返回页面内容。

示例2:多用户在线聊天室

在在线聊天室中,我们需要使用session来识别不同的用户,并将发送的消息通知给所有的在线用户。具体实现方法类似于示例中用户登录功能的处理方式。

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

// 设置session加密秘钥
app.use(session({ secret: 'keyboard cat' }));

// 网页聊天室页面
app.get('/', (req, res) => {
  res.send(`
    <h1>Chat Room</h1>
    <ul id="messages"></ul>
    <input id="message" type="text">
    <button onclick="send()">Send</button>
    <script>
      function send() {
        const msg = document.getElementById('message').value;
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/message');
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify({ message: msg }));
      }
      const source = new EventSource('/stream');
      source.onmessage = function(event) {
        const el = document.createElement('li');
        el.innerHTML = event.data;
        document.getElementById('messages').appendChild(el);
      };
    </script>
  `);
});

// 处理发送消息的请求
app.post('/message', (req, res) => {
  // 判断用户是否已经登录
  if(req.session.user) {
    // 向所有在线用户发送消息
    const msg = `${req.session.user.username}: ${req.body.message}`;
    const clients = req.app.get('clients');
    clients.forEach(client => client.send(msg));
    res.send('Success');
  } else {
    res.send('Unauthorized');
  }
});

// 处理用户登录请求
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  // 模拟用户信息验证
  if (username === 'admin' && password === '123456') {
    // 设置session信息
    req.session.user = { username };
    // 重定向到网页聊天室页面
    res.redirect('/');
  } else {
    // 登录失败
    res.send('Login failed');
  }
});

// 处理用户注销请求
app.get('/logout', (req, res) => {
  // 清除session信息
  req.session.destroy();
  // 重定向到用户登录页面
  res.redirect('/');
});

// 处理SSE请求
app.get('/stream', (req, res) => {
  // 添加客户端到clients数组中
  const clients = req.app.get('clients');
  clients.push(res);
  // 向客户端发送SSE消息
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.write('\n');
  req.on('close', () => {
    // 从clients数组中移除客户端
    clients.splice(clients.indexOf(res), 1);
  });
});

// 启动应用
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws, req) => {
  console.log('WebSocket connected');
  // 将WebSocket连接保存到clients数组中
  req.app.get('clients').push(ws);
  ws.on('close', () => {
    console.log('WebSocket disconnected');
    // 从clients数组中移除WebSocket连接
    const clients = req.app.get('clients');
    clients.splice(clients.indexOf(ws), 1);
  });
});
app.set('clients', []);

// 启动应用
app.listen(3000, () => {
  console.log('App is running at http://localhost:3000');
});

在上述示例中,我们使用session来识别不同的用户,并在处理发送消息的请求时进行合法性验证。在接收到发送消息的请求,并验证用户身份合法后,我们向所有的在线用户发送消息。在页面中,我们通过SSE(Server-Sent Events)来实现实时消息的推送。在用户访问聊天室页面时,我们使用session来验证用户的身份是否已经通过认证,如果认证成功则显示该页面;否则重定向到用户登录页面。在客户端发送消息时,我们使用WebSocket将该消息发送到服务端,并向所有在线客户端广播该消息的内容。

至此,我们详细讲解了“Nodejs进阶:express+session实现简易登录身份认证”的完整攻略。希望能对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Nodejs进阶:express+session实现简易登录身份认证 - Python技术站

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

相关文章

  • Sequelize中用group by进行分组聚合查询

    下面我来详细讲解一下“Sequelize中用group by进行分组聚合查询”的完整攻略。 什么是group by查询? 在Sequelize中,group by查询是指将某个表按照某个字段分组,然后对每个分组进行聚合操作,比如求和、平均值等,从而得到每个分组的统计结果。 分组聚合查询的语法 在Sequelize中,我们可以使用.findAll()方法进行分…

    node js 2023年6月8日
    00
  • Node.js实现http请求服务与Mysql数据库操作方法详解

    Node.js是一个开源的Javascript运行时环境,可以在服务器端使用Javascript进行编程,其强大的异步事件驱动机制和高效的I/O操作使得Node.js在Web开发中受到了广泛的应用。本文将从两个方面介绍如何使用Node.js实现http请求服务和Mysql数据库操作。 Node.js实现http请求服务 在Node.js中,我们可以使用htt…

    node js 2023年6月8日
    00
  • Vue虚拟dom被创建的方法

    在Vue中,虚拟DOM是由Vue内部的渲染函数或模板编译器创建的。创建虚拟DOM的方法有两种:手动使用渲染函数和自动使用模板编译器。 手动使用渲染函数 使用Vue提供的渲染函数可以手动的创建虚拟DOM。渲染函数是一个函数式组件,它接收一个用于描述组件模板的函数createElement作为参数,并返回一个表示组件VNode节点的JavaScript对象。下面…

    node js 2023年6月8日
    00
  • js中关于require与import的区别及说明

    JS中关于require与import的区别及说明 定义 在JS中,require和import均是用于导入其他模块的关键字,在使用其他模块中的代码时至关重要。但它们的语法和用法是不同的,而这正是二者之间的主要区别。 require require是一种CommonJS规范中定义的关键字。 它仅用于Node.js中的模块管理,并不适用于Web浏览器环境下的J…

    node js 2023年6月8日
    00
  • 浅谈node的事件机制

    浅谈 Node 的事件机制 1. Node.js 事件机制简介 Node.js 的事件机制是基于观察者模式实现的,包含两个主要部分:事件的触发器(EventEmitter)和事件的监听器(Listener)。 其中 EventEmitter 是具有发布-订阅(publish-subscribe)模式功能的对象,用来触发事件和传递数据,而 Listener 则…

    node js 2023年6月8日
    00
  • nodejs实现百度舆情接口应用示例

    为了讲解“nodejs实现百度舆情接口应用示例”的完整攻略,我们需要先了解以下几个内容: 什么是Node.js 什么是百度舆情接口 如何使用Node.js实现百度舆情接口应用示例 1. 什么是Node.js Node.js是一个基于Chrome V8引擎的JavaScript运行环境,其主要用于快速、轻松地构建高性能、可伸缩的网络应用程序。在Node.js环…

    node js 2023年6月8日
    00
  • 把Node.js程序加入服务实现随机启动

    将Node.js程序加入系统服务可以实现开机自动启动,无需手动执行命令,保证Node.js程序一直运行,提高服务的可靠性。下面是将Node.js程序加入服务的攻略。 1. 安装node-windows 需要使用node-windows模块将Node.js程序加入系统服务。可以使用npm安装node-windows: npm install -g node-w…

    node js 2023年6月8日
    00
  • nodejs高版本降为低版本的详细解决方案

    下面我就详细讲解“nodejs高版本降为低版本的详细解决方案”的完整攻略,包括以下几个步骤: 1. 确定要求的低版本 首先,需要确定要将Node.js版本降到哪个低版本。建议在Node.js官方文档中,查找要求的低版本Node.js的版本号和下载地址。例如,我们要将Node.js版本降级到v12.18.4,那么可以在官网中找到该版本的下载页面:https:/…

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