使用 NodeJS 进行用户身份验证和授权的不同方法 - 第一部分 基于会话的身份验证

2025-05-25

使用 NodeJS 进行用户身份验证和授权的不同方法(第一部分)

基于会话的身份验证

首先让我们解决身份验证授权的争论。

验证

这是验证用户是否说实话的过程。例如:当我们使用用户名和密码登录账户时,我们会根据数据库中存储的信息验证这些凭证,并确认用户是否是其本人,这个过程称为身份验证。

授权

了解用户有权访问哪些信息是一个安全过程。授权的典型例子包括授予某人下载服务器上特定文件的权限,或授予单个用户对应用程序的管理权限。

在本文中,我们将研究使用 NodeJS 进行用户身份验证的两种不同方法

  • 基于会话的身份验证
  • 基于令牌的身份验证

先决条件

  • NodeJS
  • MongoDB(您可以使用 Atlas 帐户或本地 mongodb 连接)

npm使用或任何你喜欢的方式设置一个新的 NodeJS 项目yarn

基于会话的身份验证

会话身份验证.png

这张图非常简单地概括了基于会话的身份验证。让我们用代码来实现它,以便更好地理解。

在项目目录中的终端上执行以下代码行。

npm install express express-session mongoose connect-mongo

express - 用于创建我们的服务器
express-session - 用于创建基于会话的身份验证
mongoose - 连接到我们的 MongoDB 数据库
connect-mongo - 用于将我们的会话存储在 MongoDB 数据库中

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo');
const session = require('express-session');

await mongoose.connect('your_mongo_url', (err, db) => {
            console.log('MongoDB Connected....');
      });

app.get('/', (req,res)=>{
    res.send('<h1>Hello World!</h1>')  
})

app.listen(5000, () => console.log(`Server 🔥🔥🔥 up on 5000`));
Enter fullscreen mode Exit fullscreen mode

这段代码将使我们的服务器在端口 5000 上启动并运行。因此,如果您现在访问http://localhost:5000/,您将看到所需的结果。

现在让我们配置 MongoDB 存储以进行会话存储。

app.use(session({
    secret: 'fiwafhiwfwhvuwvu9hvvvwv', // Never ever share this secret in production, keep this in separate file on environmental variable
    resave: false,
    saveUninitialized: true,
    cookie: { maxAge: oneDay },
    store: MongoStore.create({
        mongoUrl: 'your_mongo_url'
    })
}));
Enter fullscreen mode Exit fullscreen mode

这段代码使用了 express-session 包来为请求创建一个空的 Session 对象。
请参阅此链接,了解该对象中的 saveUninitialized 和 resave 属性。

因此,这将在我们的 mongodb 数据库中创建一个新的空会话,其集合名称为 session。

让我们为用户创建一个登录路由

app.post('/login', async (req, res) => {
    const { username, password } = req.body;    
try {
        let user = await User.findOne({ email: username })
        req.session.userId = user.id;

        console.log(req.session);

        res.redirect('/dashboard')

    } catch (err) {
        console.log(err);
        res.json({ msg: 'Server Error! Please reload page' });
    }
})
Enter fullscreen mode Exit fullscreen mode

现在这部分代码很重要。现在,当用户使用用户名和密码登录其帐户时,我们会将该请求发送到服务器,并将其存储在会话中。req.session.userId会话中存储用户的唯一 _id,服务器会创建一个唯一的会话 ID,并将其放入 Cookie 中,该 Cookie 将被发送回客户端并存储在客户端浏览器中。现在,每当客户端向服务器发出任何请求时,请求头都会包含此 Cookie,我们在服务器端可以使用请求头中的 Cookie 并获取用户的 userId 来验证该特定用户的身份。

module.exports.authentication = async (req, res, next) => {
    const userId = req.session.userId;
    if (!userId) {
        return res.redirect('/login?q=session-expired');
    }
    try {
        let user = await User.findById(userId);
        if (!user) {
            return res.redirect('/login?q=session-expired');
        }
        next();
    } catch (err) {
        console.log(err);
        res.json({ msg: 'Server error. Please reload page after sometime' })
    }
};
Enter fullscreen mode Exit fullscreen mode

我们可以创建这种类型的中间件功能,对于受保护路线(如仪表板、预订历史记录、付款路线等)上的每个请求,我们都可以验证用户并根据用户显示正确的数据。

基于会话的身份验证的优势

  • Cookies 是小尺寸的值,易于使用和实现,并且可以撤销 cookies 的有效性。

基于会话的身份验证的缺点

  • 会话存储在服务器/数据库中而不是客户端,因此当同时有大量请求时,项目扩展变得非常困难。

这时,基于令牌的身份验证(一种现代且可扩展的解决方案)就派上用场了。它解决了会话身份验证中最大的难题——令牌存储在客户端浏览器中,从而让应用程序的扩展变得非常简单。
敬请期待第二部分,我们将在其中详细讨论基于令牌的身份验证。

给我买杯咖啡

文章来源:https://dev.to/lavig10/ Different-ways-for-user-authentication-with-nodejs-1odj
PREV
利用游戏设计让虚拟活动更具社交性
NEXT
技术职业指南咨询个人贡献者用户体验工程师用户界面设计网站可靠性工程师安全开发者关系工程经理元