目录
一、Token 详解
1. Token 的定义与作用
2. Token 的工作流程
3. Token 的优势
4. Token 的安全实践
5. JWT 结构示例
二、Axios 拦截器详解
1. 拦截器的作用
2. 请求拦截器
3. 响应拦截器
4. 拦截器常见场景
5. 移除拦截器
三、完整代码示例
四、总结
五、axios高级配置
1. 全局默认配置
2. 创建实例(隔离配置)
3. 取消请求
4. 并发请求
5. 文件上传
6. 文件下载
六、XSS(跨站脚本攻击)
1. 攻击原理
2. 攻击示例
3. 防御措施
七、CSRF(跨站请求伪造)
1. 攻击原理
2. 防御措施
八、Token 在防御中的应用
1. Token 类型
2. 安全实践
3. JWT 安全增强
九、总结
一、Token 详解
1. Token 的定义与作用
Token(令牌)是用于在客户端和服务器之间安全传递用户身份信息的一种凭证,通常用于身份验证和授权流程。
-
核心作用:
-
身份验证(Authentication):验证用户身份(如登录状态)。
-
授权(Authorization):授予用户访问特定资源的权限(如 API 端点)。
-
-
常见类型:
-
JWT(JSON Web Token):最流行的无状态令牌格式,包含头部、载荷和签名。
-
OAuth2 Token:用于第三方授权(如使用 Google 登录)。
-
Session Token:传统有状态会话标识(如 Session ID)。
-
2. Token 的工作流程
1. 用户登录 → 服务器验证凭据 → 生成 Token → 返回给客户端
2. 客户端存储 Token(如 localStorage、Cookie)
3. 客户端发起请求时携带 Token(通常通过 HTTP 头)
4. 服务器验证 Token → 授权访问资源
3. Token 的优势
-
无状态性:服务器无需存储会话信息(适合分布式系统)。
-
跨域支持:易于在多个服务间传递用户身份(如微服务架构)。
-
安全性:可通过签名(JWT)或加密防止篡改。
4. Token 的安全实践
-
存储方式:
-
推荐:使用
httpOnly
、Secure
、SameSite=Strict
的 Cookie(防 XSS)。 -
次选:
localStorage
或sessionStorage
(需防范 XSS)。
-
-
传输方式:
-
通过
Authorization
请求头传输(如Bearer <token>
)。
-
-
过期时间:
-
设置短期有效的 Token(如 15 分钟),配合 Refresh Token 续期。
-
5. JWT 结构示例
Header: {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "user123", "exp": 1620000000}
Signature: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
二、Axios 拦截器详解
1. 拦截器的作用
拦截器允许在请求发送前或响应返回后,统一添加逻辑(如添加 Token、处理错误)。
2. 请求拦截器
axios.interceptors.request.use(
config => {
// 请求发送前的处理(如添加 Token)
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
// 请求错误处理
return Promise.reject(error);
}
);
3. 响应拦截器
axios.interceptors.response.use(
response => {
// 响应成功处理(状态码 2xx)
return response.data; // 直接返回数据,简化后续处理
},
async error => {
// 响应错误处理(状态码非 2xx 或网络错误)
const originalRequest = error.config;
// Token 过期且未重试过 → 尝试刷新 Token
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const newToken = await refreshToken(); // 刷新 Token
localStorage.setItem('token', newToken);
originalRequest.headers.Authorization = `Bearer ${newToken}`;
return axios(originalRequest); // 重试原请求
} catch (refreshError) {
logout(); // 刷新失败 → 跳转登录页
return Promise.reject(refreshError);
}
}
// 其他错误统一处理
return Promise.reject(error);
}
);
4. 拦截器常见场景
-
自动添加 Token:统一为所有请求添加
Authorization
头。 -
Token 过期自动刷新:401 错误时刷新 Token 并重试请求。
-
统一错误处理:网络错误、服务器错误等全局捕获。
-
加载状态管理:显示/隐藏全局加载动画。
5. 移除拦截器
const requestInterceptor = axios.interceptors.request.use(...);
const responseInterceptor = axios.interceptors.response.use(...);
// 移除拦截器
axios.interceptors.request.eject(requestInterceptor);
axios.interceptors.response.eject(responseInterceptor);
三、完整代码示例
1. Token 管理 + Axios 拦截器
// 封装 Axios 实例
const api = axios.create({
baseURL: 'https://api.example.com',
});
// 请求拦截器:添加 Token
api.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
// 响应拦截器:处理 Token 过期
api.interceptors.response.use(
response => response.data,
async error => {
const originalRequest = error.config;
// Token 过期且未重试过
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const newToken = await refreshToken();
localStorage.setItem('token', newToken);
originalRequest.headers.Authorization = `Bearer ${newToken}`;
return api(originalRequest);
} catch (refreshError) {
logout();
return Promise.reject(refreshError);
}
}
// 其他错误处理
return Promise.reject(error);
}
);
// 刷新 Token 的函数
async function refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
const response = await axios.post('/auth/refresh', { refreshToken });
return response.data.token;
}
// 退出登录
function logout() {
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
window.location.href = '/login';
}
四、总结
-
Token:身份验证与授权的核心凭证,需安全存储和传输。
-
Axios 拦截器:实现全局请求/响应逻辑(如 Token 管理、错误处理),提升代码复用性和可维护性。
-
最佳实践:
-
使用
httpOnly
Cookie 存储 Token(防 XSS)。 -
短期 Token + Refresh Token 提升安全性。
-
拦截器中处理 Token 刷新避免并发问题。
-
五、axios高级配置
1. 全局默认配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer token123';
axios.defaults.timeout = 5000; // 超时时间(毫秒)
2. 创建实例(隔离配置)
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 3000
});
api.get('/data'); // 使用实例发送请求
3. 取消请求
使用 CancelToken(旧版):
const source = axios.CancelToken.source();
axios.get('/data', {
cancelToken: source.token
}).catch(error => {
if (axios.isCancel(error)) {
console.log('请求被取消:', error.message);
}
});
// 取消请求
source.cancel('用户手动取消');
使用 AbortController(新版,推荐):
const controller = new AbortController();
axios.get('/data', {
signal: controller.signal
}).catch(error => {
if (error.name === 'CanceledError') {
console.log('请求已取消');
}
});
// 取消请求
controller.abort();
4. 并发请求
const request1 = axios.get('/data1');
const request2 = axios.get('/data2');
axios.all([request1, request2])
.then(axios.spread((res1, res2) => {
console.log(res1.data, res2.data);
}));
5. 文件上传
const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
6. 文件下载
axios.get('/download', {
responseType: 'blob' // 指定响应类型为二进制流
}).then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
});
六、XSS(跨站脚本攻击)
1. 攻击原理
-
定义:攻击者向网页注入恶意脚本(JavaScript、HTML、CSS),当其他用户访问该页面时,脚本在用户浏览器执行,窃取数据或劫持会话。
-
类型:
-
存储型 XSS:恶意脚本永久存储在目标服务器(如论坛评论)。
-
反射型 XSS:恶意脚本通过 URL 参数反射到页面(如钓鱼链接)。
-
DOM 型 XSS:前端 JavaScript 动态修改 DOM 时触发漏洞。
-
2. 攻击示例
// 用户输入未过滤,直接渲染到页面
用户评论内容:<script>stealCookie()</script>
3. 防御措施
-
输入过滤与转义:
-
对用户输入的内容进行 HTML 转义(如
<
→<
)。 -
使用安全的库(如
DOMPurify
)清理 HTML。
-
-
Content Security Policy(CSP):
Content-Security-Policy: default-src 'self'; script-src 'self' trusted.com
-
限制页面只能加载指定来源的脚本、样式等资源。
-
-
设置 HttpOnly Cookie:
-
防止 JavaScript 通过
document.cookie
读取敏感 Cookie。
// 服务器设置 Cookie Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
-
七、CSRF(跨站请求伪造)
1. 攻击原理
-
定义:攻击者诱导用户访问恶意页面,该页面自动向目标网站发起请求(利用用户已登录的 Cookie)。
-
示例:
<!-- 恶意页面中的图片标签 --> <img src="https://bank.com/transfer?to=attacker&amount=1000">
2. 防御措施
-
CSRF Token:
-
服务器生成随机 Token 嵌入表单或请求头,验证请求的合法性。
<form action="/transfer" method="POST"> <input type="hidden" name="csrf_token" value="随机值"> </form>
-
-
SameSite Cookie:
-
限制 Cookie 仅在相同站点请求中发送。
Set-Cookie: sessionId=abc123; SameSite=Strict; Secure
-
Strict:完全禁止第三方 Cookie。
-
Lax:允许安全导航(如链接跳转)携带 Cookie。
-
None:允许所有请求携带 Cookie(需配合
Secure
)。
-
-
验证请求来源:
-
检查
Origin
或Referer
头部是否来自合法域名。
-
八、Token 在防御中的应用
1. Token 类型
-
CSRF Token:防御 CSRF 攻击,确保请求来自合法页面。
-
JWT(JSON Web Token):用于无状态身份验证,包含签名防篡改。
2. 安全实践
-
存储方式:
-
CSRF Token:存储在服务器 Session 或加密 Cookie 中。
-
JWT:通过
httpOnly
+Secure
Cookie 存储,或前端存储但结合短期有效期。
-
-
传输方式:
-
CSRF Token:嵌入表单隐藏字段或请求头(如
X-CSRF-Token
)。 -
JWT:通过
Authorization: Bearer <token>
请求头传输。
-
3. JWT 安全增强
-
签名验证:使用强加密算法(如 HS256、RS256)。
-
有效期控制:设置短期有效的
exp
字段,配合 Refresh Token 续期。 -
黑名单机制:注销时使特定 Token 失效。
九、总结
-
XSS 防御核心:防止恶意脚本注入,隔离用户输入与代码执行。
-
CSRF 防御核心:确保请求来源合法,阻断伪造请求。
-
Token 安全:结合存储安全(HttpOnly)、传输安全(HTTPS)和有效期管理。
综合防御策略:
攻击类型 | 防御措施 |
---|---|
XSS | 输入过滤 + CSP + HttpOnly Cookie + 避免 innerHTML 直接渲染用户输入。 |
CSRF | CSRF Token + SameSite Cookie + 验证请求来源。 |
Token 安全 | 使用 HTTPS + 安全存储(HttpOnly Cookie) + 短期有效 + 签名验证。 |