🔐 基于会话的身份验证与基于令牌的身份验证:哪个更好?🤔

2025-05-24

🔐 基于会话的身份验证与基于令牌的身份验证:哪个更好?🤔

各位读者好!✋ 希望您一切顺利。本文将介绍后端应用程序中常用的会话和基于令牌的身份验证方法。让我们来一探究竟。

🔐 基于会话的身份验证

简单来说,基于会话的身份验证使用存储在您设备上的特殊代码(会话 ID)来记住您访问网站时的身份,从而保持您的登录状态并记住您的信息,直到您离开或注销。没明白吗?别担心,让我们一步一步来。

1.用户登录:

用户通过特殊请求向服务器发送电子邮件和密码来登录。

2. 检查详情:

服务器检查所提供的详细信息是否与用户存储的信息相符。

3.创建会话:

如果一切正确,服务器会创建一个“会话”,用于保存用户信息(例如用户 ID、权限和时间限制)。这些信息安全地保存在服务器的存储空间中。考试或考试也可以使用诸如 之类的库进行管理express-session

4.获取会话ID:

服务器将此“会话 ID”发送回用户的设备,通常作为响应中的 cookie。

5.使用会话ID:

每当用户需要从服务器获取某些内容时,他们的设备都会自动在请求中包含此会话 ID。

6.服务器检查:

服务器使用此会话ID在会话存储中查找有关会话用户的存储信息。

下面让我们来看一下express-session它的工作原理:

  • 当用户登录时,服务器会为该用户创建一个会话,并在包含会话 ID 的响应中设置一个 cookie🍪。

  • 浏览器会在后续对服务器的请求中自动包含此会话 ID cookie🍪。

  • 当服务器收到请求时,express-session 中间件使用 cookie🍪 中的会话 ID 来检索相关的会话数据。

  • req.session中存储的数据(例如 userId)可用于处理请求。

7. 授予访问权限:

如果一切都匹配,服务器就知道用户是真实的,并响应他们的请求。

会话身份验证工作

例子

下面是一个使用 Express.js 实现会话身份验证的 Node.js 应用程序示例。

执行



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

const app = express();

// Middleware setup
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true, // Set the cookie as HTTP-only, Optional
maxAge: 60*30 // In secs, Optional
}
}));

Enter fullscreen mode Exit fullscreen mode




登录路线




app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);

if (user) {
req.session.userId = user.id; // Store user ID in session
res.send('Login successful');
} else {
res.status(401).send('Invalid credentials');
}
});

Enter fullscreen mode Exit fullscreen mode




受保护的路线




app.get('/home', (req, res) => {
if (req.session.userId) {
// User is authenticated
res.send(Welcome to the Home page, User </span><span class="p">${</span><span class="nx">req</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nx">userId</span><span class="p">}</span><span class="s2">!);
} else {
// User is not authenticated
res.status(401).send('Unauthorized');
}
});

Enter fullscreen mode Exit fullscreen mode




注销路线




app.get('/logout', (req, res) => {
req.session.destroy(err => {
if (err) {
res.status(500).send('Error logging out');
} else {
res.redirect('/'); // Redirect to the home page after logout
}
});
});

Enter fullscreen mode Exit fullscreen mode




🔐 基于令牌的身份验证

JWT 身份验证使用包含用户信息的数字签名令牌,允许安全且经过验证地访问网站或应用程序,而无需重复登录。让我们看一下基于令牌的身份验证的分步工作流程。

1.用户登录请求:

用户通过特定请求向服务器发送其电子邮件和密码来登录。

2. 凭证验证:

服务器根据存储的用户数据验证所提供的凭证。

3. 代币生成:

验证成功后,服务器会创建一个令牌(通常为 JWT - JSON Web Token)。该令牌包含用户信息(声明),例如 user_id、权限等。

4. 令牌签名和哈希:

该令牌使用密钥进行签名,并使用哈希算法(如 SHA256)进行处理以创建哈希。

5.发送令牌:

服务器将此令牌发送到客户端,客户端将其存储在浏览器中。

6. 代币存储选项:

客户端可以使用多种方式存储令牌,例如 HttpOnly Cookies、会话存储或本地存储。建议使用 HttpOnly Cookies 存储,因为它可以阻止 JavaScript 访问,从而增强抵御 XSS 攻击的安全性。

7. 令牌到期及安全:

令牌通常有一个到期时间以增强安全性。

8.在请求中包含Token:

对于对服务器的每个请求,客户端都会在授权标头中发送令牌。

在令牌前添加“Bearer”是一种很好的做法。



axios.get(URL, {
headers: {
'Authorization': 'Bearer ' + token,
},
})

Enter fullscreen mode Exit fullscreen mode



  1. 服务器端验证:

收到请求后,服务器会检索令牌。

10.令牌验证和用户身份验证:

服务器使用密钥验证令牌并从中提取声明。如果声明中的用户信息存在于服务器的用户表中,则服务器对用户进行身份验证,并授予其对所请求资源的访问权限。

基于令牌的身份验证

例子

登录



app.post('/login', (req, res) => {

const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);

jwt.sign({ user }, secretKey, { expiresIn: '1h' }, (err, token) => {
if (err) {
res.status(500).send('Error generating token');
} else {
res.json({ token });
}
});
});

Enter fullscreen mode Exit fullscreen mode




受保护的路线

我们为每个需要验证的路由使用veriyToken()函数作为中间件。请求会经过该函数veriyToken(),只有当该next()函数被调用时,它才会传递到该路由并执行代码。



app.get('/dashboard', verifyToken, (req, res) => {
res.send('Welcome to the Home page');
});

// Verify token middleware
function verifyToken(req, res, next) {
const token = req.headers['authorization'];

if (typeof token !== 'undefined') {
jwt.verify(token.split(' ')[1], secretKey, (err, decoded) => {
if (err) {
res.status(403).send('Invalid token');
} else {
req.user = decoded.user;
next();
}
});
} else {
res.status(401).send('Unauthorized');
}
}

Enter fullscreen mode Exit fullscreen mode




主要区别

  • 存储位置: Session存储在服务端,Token(JWT)存储在客户端。

  • 有状态与无状态:会话是有状态的,而令牌是无状态的,从而允许分布式系统具有更好的可扩展性。

  • 到期处理:会话到期由服务器管理,而令牌到期由令牌本身处理。

  • 安全措施: JWT 通常包括数字签名和加密支持,与使用 cookie 的典型会话机制相比增强了安全性,但如果没有得到适当的保护,则容易受到 CSRF 攻击。

  • 使用灵活性:令牌(JWT)在携带身份验证之外的附加信息方面提供了更大的灵活性,对于授权和自定义数据传输很有用。

应该使用哪种方法?

这取决于应用程序的需求和性质。大多数应用程序使用混合方法:API 使用基于令牌的身份验证,Web 交互使用基于会话的身份验证。

希望你喜欢这篇文章,如果喜欢的话,别忘了点赞哦!你的项目用的是哪种后端语言?🤔

在下面评论👇

与我联系-

文章来源:https://dev.to/fidalmathew/session-based-vs-token-based-authentication-which-is-better-227o
PREV
作为 Web 开发初学者开始为开源做出贡献
NEXT
响应式设计 CSS 技巧