javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端身份认证与Token安全

前端身份认证与Token安全示例详解

作者:全栈前端老曹

前端安全防护是一项系统且重要的工作,开发者需要对常见的安全漏洞和攻击方式有清晰的认识,并掌握相应的防护策略,这篇文章主要介绍了前端身份认证与Token安全的相关资料,需要的朋友可以参考下

1. 为什么需要安全的身份认证?

随着 Web 应用的普及,用户登录和会话管理成为关键功能。然而,传统的基于 Session 的认证方式存在扩展性差、跨域支持不足等问题。而基于 Token 的认证方式不仅解决了这些问题,还能有效提升系统的安全性和性能。

2. 学习目标

JWT 结构详解

1. 什么是 JWT?

JWT 是一种紧凑、自包含的 Token 格式,用于在客户端和服务器之间传递声明(Claims)。它由三部分组成:

示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

2. JWT 的组成部分

(1) Header

定义 Token 的类型和签名算法。例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

(2) Payload

存储用户信息或声明。例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

(3) Signature

通过以下公式生成:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

签名机制详解

1. 签名的作用

签名确保 Token 的完整性和真实性,防止篡改和伪造。

2. 常见算法

示例(Node.js 实现 HMAC 签名):

const crypto = require('crypto');

const header = { alg: 'HS256', typ: 'JWT' };
const payload = { sub: '1234567890', name: 'John Doe', iat: 1516239022 };
const secret = 'your-secret-key';

const base64Header = Buffer.from(JSON.stringify(header)).toString('base64');
const base64Payload = Buffer.from(JSON.stringify(payload)).toString('base64');
const signature = crypto
  .createHmac('sha256', secret)
  .update(`${base64Header}.${base64Payload}`)
  .digest('base64');

console.log(`${base64Header}.${base64Payload}.${signature}`);

本地存储安全

1. 存储方式对比

(1)localStorage

优点:持久化存储,适合长期保存 Token。
缺点:易受 XSS 攻击。

(2)sessionStorage

优点:仅在当前会话中有效,关闭浏览器后清除。
缺点:同样易受 XSS 攻击。

(3)HttpOnly Cookie

优点:无法被 JavaScript 访问,防御 XSS 攻击。
缺点:需手动设置,且可能受到 CSRF 攻击。

2. 最佳实践

刷新令牌策略

1. 为什么需要刷新令牌?

Access Token 通常具有较短的有效期,以降低泄露风险。而 Refresh Token 用于获取新的 Access Token,从而避免频繁登录。

2. 设计思路

(1) Access Token

(2) Refresh Token

(3) 刷新流程

  1. 客户端检测 Access Token 是否过期。
  2. 如果过期,向服务器发送 Refresh Token 请求新的 Access Token。
  3. 服务器验证 Refresh Token 的合法性并返回新的 Access Token。

示例(Node.js 实现刷新逻辑):

app.post('/refresh-token', (req, res) => {
  const refreshToken = req.cookies.refreshToken;

  if (!refreshToken || !validateRefreshToken(refreshToken)) {
    return res.status(401).send('Invalid refresh token');
  }

  const newAccessToken = generateAccessToken({ userId: 123 });
  res.json({ accessToken: newAccessToken });
});

代码讲解:实际项目中的实现

1. Vue 项目中的 JWT 验证

在 Vue 中使用 axios 拦截器处理 Token:

import axios from 'axios';

axios.interceptors.request.use((config) => {
  const token = localStorage.getItem('accessToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

axios.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response.status === 401) {
      const newToken = await refreshToken();
      error.config.headers.Authorization = `Bearer ${newToken}`;
      return axios(error.config);
    }
    return Promise.reject(error);
  }
);

2. React 项目中的 Token 存储

在 React 中使用 HttpOnly Cookie 存储 Refresh Token:

// 登录接口
fetch('/api/login', {
  method: 'POST',
  body: JSON.stringify({ username, password }),
  credentials: 'include'
});

// 刷新 Token 接口
fetch('/api/refresh-token', {
  method: 'POST',
  credentials: 'include'
});

总结

1. 核心知识点回顾

2. 实践建议

到此这篇关于前端身份认证与Token安全的文章就介绍到这了,更多相关前端身份认证与Token安全内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文