reactjs - Axios - 提取 http cookie 并将其设置为授权标头
问题描述
我正在为我的应用程序构建身份验证,并且正在使用访问和刷新令牌。
用户登录后,API 发出 3 件事
- 刷新令牌
- 访问带有标头和有效负载的令牌字符串
- 访问带有签名的令牌字符串
这些令牌都是jwt
令牌。
本文讨论了为什么应该拆分访问令牌。
使用 express,我将令牌发送回控制器中的浏览器,如下所示:
res.cookie(
ACCESS_TOKEN_COOKIE_HEADER_PAYLOAD,
headerAndPayload,
COOKIE_OPTIONS,
)
res.cookie(
ACCESS_TOKEN_COOKIE_SIGNATURE,
signature,
COOKIE_OPTIONS_HTTP_ONLY,
)
res.cookie(REFRESH_TOKEN_COOKIE, refreshToken, COOKIE_OPTIONS)
return res.json({ username, uid })
auth.constants.ts
export const COOKIE_OPTIONS: CookieOptions = {
secure: true,
sameSite: 'lax',
}
export const COOKIE_OPTIONS_HTTP_ONLY: CookieOptions = {
httpOnly: true,
secure: true,
sameSite: 'lax',
}
export const ACCESS_TOKEN_COOKIE_HEADER_PAYLOAD = 'access_token_header_payload'
export const ACCESS_TOKEN_COOKIE_SIGNATURE = 'access_token_signature'
export const REFRESH_TOKEN_COOKIE = 'refresh_token'
在 ui (react) 中,我进入 Chrome devtools -> application -> storage -> cookeis,我可以看到它们在我每次登录时都会更新。这是我想要的行为,所以到目前为止很好。
现在,当我想向我的 API 发送请求以创建某些内容时(假设我正在创建一个新的博客文章),我想获取这些 cookie 并将它们作为Authorization
Header 传递。
我正在遵循这个人的建议,但我注意到他正在使用store
我猜是某种形式的状态。由于我没有这样做,并且多个来源(来源 1、来源 2)指出将令牌发送到 API 以进行身份验证的标准是使用Authorization
标头,因此我想遵循这一点。
目前,当我使用 axios 发出 API 请求时,我会在控制台记录 expressrequest
对象,并且可以在 cookie 中看到我的令牌,如下所示:
headers: {
host: 'localhost:3001',
connection: 'keep-alive',
'content-length': '0',
accept: 'application/json, text/plain, */*',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
origin: 'http://localhost:3000',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'http://localhost:3000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
cookie: 'access_token_header_payload=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvc3R5cG9vIiwiaWF0IjoxNTk2ODM0MDIwLCJleHAiOjE1OTY4MzQwODB9; access_token_signature=3pUbxjWgly9xmYSJObOvTgps9qwjOIrHWWE4LPYidmQ; refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvc3R5cG9vIiwiaWF0IjoxNTk2ODM0MDIwLCJleHAiOjE1OTc0Mzg4MjB9.IKdRsaTTgAeUfwicLcBpRvw89WgYXy_rCRN5o2BJFqY'
},
但我想改为发送这些 cookie Authorization: Bearer <tokens>
。我将如何在 axios 中做到这一点?或者我在做什么安全?
这是我的 axios 拦截器
import axios from 'axios'
const service = axios.create({
withCredentials: true,
baseURL: process.env.REACT_APP_API_BASE_URL,
timeout: 5000,
})
// Request interceptors
service.interceptors.request.use(
config => {
return config
},
error => {
return Promise.reject(error)
},
)
// Response interceptors
service.interceptors.response.use(
response => {
console.log('response', response)
return response.data
},
error => {
return Promise.reject({ ...error })
},
)
export default service
解决方案
HttpOnly 意味着客户端脚本无法访问 cookie,也无法从 document.cookie 中读取并传递给 axios。
事实上,HttpOnly cookie 比我认为的 http 请求标头更安全。您需要的是在服务器端解析 auth cookie,而不是解析请求标头。
推荐阅读
- python - 有没有办法在python中命名一个函数和类相同的东西?
- amazon-web-services - 有没有办法按标签列出 CloudFront 分配而不使用 ListDistributions 全部下载?
- android-studio - 我遇到这个错误 java.lang.IllegalArgumentException: 找不到类 java.lang.Object 的调用适配器
- amazon-web-services - 无法使用 localstack dynamoDB 锁定 terraform 状态:UnrecognizedClientException
- javascript - Bootstrap 4 - 在同一页面中有两个轮播会使最后一个项目出现重叠
- javascript - 如何使 Timedimension 适应 L.control.layers 函数?
- reactjs - 如何在 Highcharts React 中重绘使用 SVGRenderer 渲染的文本?
- lua - 使用 busted 测试 Lua 代码时出现零错误
- python - 如何在 Python(Flask) 中模拟一个函数
- ruby-on-rails - 如何在rails中使用form_with和self join?