
前端如何储存JWT:本地存储、会话存储、Cookie。 推荐使用Cookie存储JWT,因为它具备跨站请求伪造(CSRF)保护功能,安全性较高。
使用Cookie存储JWT是一种较为安全的方式,因为它可以与HTTP Only和Secure标志配合使用,防止脚本访问和传输中的窃取。具体操作包括在服务器端设置Cookie的属性,使其在前端无法通过JavaScript访问,并且仅在HTTPS连接中传输。这种方式不仅增强了安全性,还简化了前端的处理逻辑,因为浏览器会自动携带Cookie。
一、JWT概述
JWT(JSON Web Token)是一种基于JSON的开放标准(RFC 7519),用于在网络应用环境间安全地传输信息。它的结构包含三部分:头部(Header)、载荷(Payload)和签名(Signature)。
1.1、JWT的结构
- 头部(Header):通常包含两部分,令牌的类型(JWT)和所使用的签名算法(如HMAC SHA256)。
- 载荷(Payload):是存储的声明(Claims),它包含了用户的身份信息和其他数据。
- 签名(Signature):由编码后的头部、载荷和一个密钥(secret)通过指定的算法生成,用于验证令牌的真实性。
1.2、JWT的工作原理
JWT的生成过程如下:
- 头部和载荷的Base64编码:将头部和载荷分别进行Base64编码。
- 签名生成:使用编码后的头部、载荷和密钥通过指定的算法生成签名。
- 令牌生成:将编码后的头部、载荷和签名拼接成一个字符串,中间用点(.)分隔,这就是JWT。
JWT的验证过程如下:
- 解析JWT:将JWT按照点(.)分隔成头部、载荷和签名。
- 验证签名:使用头部中指定的算法和密钥对头部和载荷进行签名生成,并与JWT中的签名进行比较。如果匹配,则验证通过。
- 读取载荷:验证通过后,可以读取载荷中的数据。
二、本地存储和会话存储
2.1、本地存储
本地存储(LocalStorage)是一种在客户端存储数据的方式,具有持久性,数据不会在浏览器关闭时丢失。使用本地存储存储JWT的优点是简单易用,但它存在一定的安全风险。
2.1.1、本地存储的优点
- 易于使用:通过简单的API即可完成数据的存储和读取。
- 持久化:数据在浏览器关闭后仍然存在,适合存储长期有效的数据。
2.1.2、本地存储的缺点
- 安全性较低:本地存储的数据可以被JavaScript直接访问,容易被XSS攻击利用。
- 不支持自动携带:需要手动在每次请求中添加JWT,增加了开发复杂度。
2.1.3、本地存储的使用
// 存储JWT
localStorage.setItem('token', jwtToken);
// 读取JWT
const token = localStorage.getItem('token');
// 删除JWT
localStorage.removeItem('token');
2.2、会话存储
会话存储(SessionStorage)与本地存储类似,但它的数据仅在当前会话期间有效,一旦关闭浏览器或标签页,数据就会被清除。
2.2.1、会话存储的优点
- 易于使用:与本地存储使用相同的API,操作简单。
- 会话级存储:数据仅在会话期间有效,适合存储临时性的数据。
2.2.2、会话存储的缺点
- 安全性较低:与本地存储一样,数据可以被JavaScript直接访问,容易受到XSS攻击。
- 不支持自动携带:需要手动在每次请求中添加JWT。
2.2.3、会话存储的使用
// 存储JWT
sessionStorage.setItem('token', jwtToken);
// 读取JWT
const token = sessionStorage.getItem('token');
// 删除JWT
sessionStorage.removeItem('token');
三、使用Cookie存储JWT
3.1、Cookie的概述
Cookie是一种在客户端存储数据的方式,通常用于保存用户的会话信息。与本地存储和会话存储不同,Cookie可以设置多个属性来增强安全性,如HTTP Only和Secure标志。
3.1.1、Cookie的优点
- 自动携带:浏览器在每次请求时会自动携带Cookie,简化了开发过程。
- 安全性高:通过设置HTTP Only和Secure标志,可以防止脚本访问和传输中的窃取。
3.1.2、Cookie的缺点
- 存储空间有限:每个Cookie的大小限制为4KB,适合存储小型数据。
- 操作复杂:需要通过特定的API或手动设置来操作Cookie。
3.2、设置Cookie存储JWT
3.2.1、在服务器端设置Cookie
在服务器端生成JWT后,可以通过响应头设置Cookie,并配置HTTP Only和Secure标志。
const jwtToken = generateJWT(user);
res.cookie('token', jwtToken, {
httpOnly: true, // 防止JavaScript访问
secure: true, // 仅在HTTPS连接中传输
maxAge: 3600000 // Cookie有效期,单位为毫秒
});
3.2.2、在客户端读取Cookie
由于Cookie设置了HTTP Only标志,JavaScript无法直接访问Cookie,但浏览器会自动在每次请求中携带Cookie。
// 在发送请求时,浏览器会自动携带Cookie
fetch('/protected-endpoint', {
method: 'GET',
credentials: 'include' // 包括Cookie在内的凭证信息
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
四、比较与总结
4.1、存储方式比较
- 本地存储和会话存储:易于使用,但安全性较低,适合存储非敏感数据。
- Cookie:安全性高,自动携带,适合存储敏感数据,但操作相对复杂。
4.2、安全性考虑
在选择存储方式时,安全性是一个重要的考量因素。为了防止XSS和CSRF攻击,推荐使用Cookie存储JWT,并配置HTTP Only和Secure标志。此外,还可以结合其他安全策略,如内容安全策略(CSP)和双重验证(2FA),进一步提升应用的安全性。
4.3、开发复杂度
使用Cookie存储JWT可以简化开发过程,因为浏览器会自动在每次请求中携带Cookie,但需要在服务器端进行配置。相比之下,本地存储和会话存储操作简单,但需要手动在每次请求中添加JWT,增加了开发复杂度。
五、实战案例
5.1、使用Cookie存储JWT的完整流程
5.1.1、服务器端生成JWT并设置Cookie
在用户登录成功后,生成JWT并通过响应头设置Cookie。
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.post('/login', (req, res) => {
const user = { id: 1, username: 'test' }; // 假设用户已通过身份验证
const jwtToken = jwt.sign(user, 'secret', { expiresIn: '1h' });
res.cookie('token', jwtToken, {
httpOnly: true,
secure: true,
maxAge: 3600000
});
res.json({ message: '登录成功' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
5.1.2、客户端发送请求时携带Cookie
在客户端发送请求时,浏览器会自动携带Cookie。
fetch('/protected-endpoint', {
method: 'GET',
credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
5.1.3、服务器端验证JWT
在受保护的端点,验证JWT的真实性,并返回相应的数据。
app.get('/protected-endpoint', (req, res) => {
const token = req.cookies.token;
if (!token) {
return res.status(401).json({ message: '未授权' });
}
jwt.verify(token, 'secret', (err, decoded) => {
if (err) {
return res.status(401).json({ message: '无效的令牌' });
}
res.json({ message: '受保护的数据', user: decoded });
});
});
5.2、结合项目管理系统
在实际项目中,管理系统的数据安全性至关重要。在使用JWT进行用户身份验证时,可以结合研发项目管理系统PingCode和通用项目协作软件Worktile,实现高效的项目管理和安全的数据存储。
5.2.1、PingCode的特点
PingCode是一款专业的研发项目管理系统,提供了全面的项目管理功能,如需求管理、缺陷管理、任务管理和版本管理等。通过与JWT的结合,可以实现用户的安全认证和权限管理,确保项目数据的安全性。
5.2.2、Worktile的特点
Worktile是一款通用的项目协作软件,适用于各类团队的项目管理和协作。它提供了任务管理、时间管理、文件共享和团队沟通等功能。通过JWT进行用户认证,可以确保用户数据的安全性和隐私性,并提升团队的协作效率。
六、总结
在前端存储JWT时,推荐使用Cookie存储,并配置HTTP Only和Secure标志,以提高安全性。虽然本地存储和会话存储操作简单,但安全性较低,适合存储非敏感数据。在实际项目中,结合研发项目管理系统PingCode和通用项目协作软件Worktile,可以实现高效的项目管理和安全的数据存储。通过合理选择存储方式和安全策略,可以有效防止XSS和CSRF攻击,保障用户数据的安全性。
相关问答FAQs:
1. 前端如何获取并储存JWT令牌?
在前端中,可以通过发送登录请求来获取JWT令牌。一旦登录成功,后端会将JWT令牌返回给前端。前端可以使用localStorage或sessionStorage等方式将JWT令牌储存起来,以便在后续的请求中使用。
2. 如何在前端使用储存的JWT令牌?
在发送需要认证的请求时,前端可以从储存的JWT令牌中获取并将其放入请求的头部中,一般使用Authorization字段。具体的做法是在请求头中添加Authorization: Bearer <JWT令牌>,其中<JWT令牌>为储存的JWT令牌。
3. 前端如何处理JWT令牌的过期问题?
JWT令牌通常会设置一个过期时间,一旦过期,就需要重新获取新的JWT令牌。为了避免在每次请求时都需要检查JWT令牌的过期时间,可以在前端使用定时器来定时检查JWT令牌是否过期。如果JWT令牌即将过期或已过期,前端可以自动发送请求获取新的JWT令牌,并更新储存的JWT令牌。这样可以确保在发送请求时,JWT令牌是有效的。
文章包含AI辅助创作,作者:Edit1,如若转载,请注明出处:https://docs.pingcode.com/baike/2197396