问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

前端如何安全地保存token

创作时间:
作者:
@小白创作中心

前端如何安全地保存token

引用
1
来源
1.
https://docs.pingcode.com/baike/2233054

在现代Web应用中,token(令牌)是实现用户身份验证和授权的重要机制。然而,如何安全地保存token是一个关键问题。本文将介绍几种常见的前端token保存方法,并分析它们的安全性和适用场景。

利用HTTP-only cookies

HTTP-only cookies是指设置了HttpOnly属性的cookies。这种cookies不能被JavaScript通过document.cookie访问,只能由服务器通过HTTP请求和响应来读取和写入。这种方式可以有效防止XSS攻击,因为即使攻击者在页面中插入了恶意的JavaScript代码,也无法读取到这些cookies。

设置HTTP-only cookies

在后端服务器中设置HTTP-only cookies。以Node.js和Express为例:

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

app.post('/login', (req, res) => {
  const token = generateToken(req.body.username); // 生成token的逻辑
  res.cookie('token', token, { httpOnly: true, secure: true }); // 设置HTTP-only cookies
  res.send('Login successful');
});

function generateToken(username) {
  // 生成token的逻辑
  return 'some-token';
}

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

读取HTTP-only cookies

由于HTTP-only cookies无法被JavaScript读取,因此需要在每次HTTP请求中将cookies自动发送到服务器。浏览器会自动将这些cookies附加到每个请求的HTTP头部。

fetch('/some-protected-endpoint', {
  method: 'GET',
  credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

保存在内存中

保存在内存中是指将token存储在JavaScript变量中,而不是持久化到本地存储或cookies中。这种方法的优点是token只存在于页面生命周期中,当用户刷新或关闭页面时,token会自动丢失,从而减少了被恶意获取的风险。

存储token

在用户登录成功后,将token保存在内存中:

let token;

function login(username, password) {
  fetch('/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ username, password })
  })
  .then(response => response.json())
  .then(data => {
    token = data.token;
  })
  .catch(error => console.error('Error:', error));
}

使用token

在后续的请求中使用内存中的token:

function fetchProtectedData() {
  fetch('/some-protected-endpoint', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}`
    }
  })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
}

不将token暴露在URL中

不将token暴露在URL中是指在进行HTTP请求时,不要将token作为查询参数或路径参数放在URL中。因为URL可能会被浏览器历史记录、日志、代理服务器等记录下来,存在泄露风险。正确的做法是将token放在HTTP请求头部的Authorization字段中。

正确的请求方式

在请求头部中添加token:

fetch('/some-protected-endpoint', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

避免错误的请求方式

不要将token放在URL中:

// 不推荐的做法
fetch(`/some-protected-endpoint?token=${token}`, {
  method: 'GET'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

总结

前端安全地保存token的方法有多种,其中最安全的方法是利用HTTP-only cookies,因为它能够有效防止XSS攻击。同时,可以将token保存在内存中,减少持久化存储带来的风险,并且在HTTP请求中避免将token暴露在URL中。综合运用这些方法,可以大大提高前端应用的安全性。

结合多种方法

在实际应用中,可以结合多种方法来提高安全性。例如,利用HTTP-only cookies来存储token,同时在内存中缓存token,在每次请求时优先使用内存中的token,只有在内存中的token失效时才从HTTP-only cookies中读取。

定期更新token

为了进一步提高安全性,可以定期更新token。例如,每隔一段时间(如1小时)重新生成一个新的token,并将旧的token作废。这样即使旧的token被泄露,也只能在短时间内被利用。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号