JWT 3:为什么 Token 要放进 Authorization?Axios 拦截器到底解决了什么?

上一篇我们已经解决了 Token 的产生和验证。

现在又出现了一个现实问题:

如果我们的项目有 20 个接口,是不是每次都要手动写:

js 复制代码
headers: {
  Authorization: `Bearer ${token}`
}

当然不是。

所以这篇来理解 Axios 的请求拦截器。


一、先看一个非常麻烦的写法

假设现在有三个 API:

js 复制代码
axios.get('/repo', {
  headers: {
    Authorization: `Bearer ${token}`
  }
})
js 复制代码
axios.get('/user', {
  headers: {
    Authorization: `Bearer ${token}`
  }
})
js 复制代码
axios.post('/order', data, {
  headers: {
    Authorization: `Bearer ${token}`
  }
})

你会发现:

每个请求都在重复处理 Token。

而 Token 本来就是整个登录系统的公共逻辑。

所以应该把它统一处理。


二、我们需要一个"请求前统一处理"的地方

我们之前已经创建了:

text 复制代码
src/api/config.js

现在它不只是负责:

js 复制代码
baseURL
timeout

还负责:

在请求发出去之前,把 Token 自动放进 Header。

Axios 提供的就是:

js 复制代码
interceptors.request

也就是:

请求拦截器。


三、添加请求拦截器

修改:

text 复制代码
src/api/config.js

代码:

js 复制代码
import axios from 'axios';

const instance = axios.create({
  baseURL: '/api',
  timeout: 5000
});

instance.interceptors.request.use(config => {
  const token = localStorage.getItem('token');

  if (token) {
    config.headers['Authorization'] = `Bearer ${token}`;
  }

  return config;
});

export default instance;

这里最关键的是:

js 复制代码
instance.interceptors.request.use(...)

可以理解成:

"以后凡是使用这个 Axios 实例发出的请求,都先让我检查一下。"


四、拦截器到底在什么时候执行?

假设页面调用:

js 复制代码
getRepo()

然后:

js 复制代码
axios.get('/repo')

请求不会直接飞出去。

而是先经过:

text 复制代码
页面调用 getRepo()
        ↓
repo.js 调用 axios.get()
        ↓
Axios 请求拦截器
        ↓
读取 localStorage 中的 Token
        ↓
添加 Authorization
        ↓
真正发送请求

所以拦截器最大的意义就是:

统一处理所有请求的公共逻辑。


五、为什么从 localStorage 里取 Token?

因为登录成功以后,我们要先把 Token 保存起来。

例如:

js 复制代码
localStorage.setItem('token', token);

以后:

js 复制代码
localStorage.getItem('token');

就能拿出来。

所以整个关系是:

text 复制代码
登录成功
    ↓
Token 保存到 localStorage
    ↓
发送任意 API 请求
    ↓
拦截器读取 Token
    ↓
添加 Authorization

六、为什么写成 Bearer?

最终我们希望 Header 是:

text 复制代码
Authorization: Bearer eyJ...

所以代码:

js 复制代码
config.headers['Authorization'] = `Bearer ${token}`;

注意这里的空格:

text 复制代码
Bearer + 空格 + Token

这就是标准的 Bearer Token 写法。

如果写成:

js 复制代码
`Bearer${token}`

就会变成:

text 复制代码
BearereyJ...

后端再按:

js 复制代码
authorization.startsWith('Bearer ')

检查时就会失败。


七、这样 API 层会变得非常干净

user.js

js 复制代码
import axios from './config';

export const login = async (data) => {
  const res = await axios.post('/login', data);
  return res.data;
}

repo.js

js 复制代码
import axios from './config';

export const getRepo = async () => {
  const res = await axios.get('/repo');
  return res.data;
}

你会发现:

这两个文件根本不需要关心 Token。

它们只需要表达:

"我要调用哪个接口。"

至于:

"有没有 Token?"
"Token 放到哪个 Header?"

这些事情统一交给 Axios。

这就是职责分离。


八、请求拦截器为什么很重要?

因为很多项目都会有一些"所有请求都要做"的事情:

text 复制代码
Token
统一 Header
请求日志
请求参数处理
Loading
统一错误处理

这些都不适合散落到业务代码里。

所以:

text 复制代码
业务代码
负责业务

拦截器
负责公共逻辑

这样项目会清晰很多。


九、服务器收到请求以后

现在浏览器发出去的请求类似:

text 复制代码
GET /api/repo

Authorization: Bearer eyJ...

Mock 后端:

js 复制代码
const authorization = req.headers?.authorization;

然后:

js 复制代码
const token = authorization.slice('Bearer '.length);

最后:

js 复制代码
jwt.verify(token, secret);

整个请求链已经完整了:

text 复制代码
页面调用 API
        ↓
Axios 请求拦截器自动添加 Token
        ↓
请求发送到 /api/repo
        ↓
Mock 读取 Authorization
        ↓
取出 Token
        ↓
jwt.verify()
        ↓
返回数据

下一篇要解决的就不是"服务器怎么验证",而是:

React 自己怎么知道当前用户有没有登录?

这就轮到 Zustand 出场了。

相关推荐
卷无止境3 小时前
智能体开发环境ADE浅析,编程工具的下一次范式跃迁
后端·python
码事漫谈6 小时前
DeepSeek 这波操作很凶
后端
CharlesYu017 小时前
前端性能优化的第一性原理,是不断缩短“用户发起意图 → 获得可用结果”之间的时间
前端
Bs_MoneyMagnet7 小时前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
平头哥技术团队7 小时前
Day 21 _ 页内锚点_给每段起个 id,目录写 href=_#id_,点一下页面就滚到那一段
前端·html·html5
子兮曰8 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
人民广场吃泡面8 小时前
什么是AI Agent?它又能给前端带来哪些效率提升?
前端·人工智能
中科三方9 小时前
两家域名注册商资质被ICANN终止:企业域名资产安全再受关注
前端·网络·安全·域名
bug总结9 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app
华无丽言10 小时前
如何在宜搭中实现获取子表中的字段值赋值到父表中?
前端·javascript·低代码