【问题标题】:Axios - extracting http cookies and setting them as authorization headersAxios - 提取 http cookie 并将其设置为授权标头
【发布时间】:2020-11-28 06:32:43
【问题描述】:

我正在为我的应用程序构建身份验证,并且正在使用访问和刷新令牌。

用户登录后,API 发出 3 件事

  • 刷新令牌
  • 访问带有标头和有效负载的令牌字符串
  • 访问带有签名的令牌字符串

这些令牌都是jwt 令牌。

This 文章讨论了为什么应该拆分访问令牌。

使用 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 传递。

我遵循this 人的建议,但我注意到他正在使用store,我猜这是某种形式的状态。由于我没有这样做,并且多个来源(source 1source 2)指出将令牌发送到 API 以进行身份​​验证的标准是使用 Authorization 标头,我想遵循这一点。

目前,当我使用 axios 发出 API 请求时,我会在控制台记录 express request 对象,并且可以在 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

【问题讨论】:

    标签: reactjs cookies axios jwt http-headers


    【解决方案1】:

    this 回复中所述,chinesedfan。授权您对后端 API 的请求的方式是通过查询解析,因为您的 cookie 是 HttpOnly 并且不能被任何客户端访问。

    使用express,这可以通过创建一个设置您的授权标头的全局中间件来完成。以下 sn-p 显示了如何执行此操作,假设您使用的是Bearer <accessToken>

    // global middleware for setting authorization header
    app.use((req, res, next) => {
      const authHeader = req.cookies.accessToken;
      if (authHeader) {
        req.headers.authorization = `Bearer ${authHeader}`;
      }
      next();
    });
    
    // initialize passportjs
    app.use(passport.initialize())
    

    在你的server.js 中添加这个中间件,假设你以这种方式命名你的初始化文件。这是您声明您的 express 应用变量的地方。

    在 express 中,中间件顺序很重要,因此请在初始化您的护照中间件之前添加此中间件。

    在您的前端,您无需向axios 添加任何内容,只需向后端发出请求,如果该请求需要授权,它将自动添加给您。

    【讨论】:

    • 我想知道除了设置withCredential:true之外我应该如何初始化授权令牌?应该是这样的:Authorization: Bearer ${mytoken}` ` 还是其他?
    【解决方案2】:

    HttpOnly 表示客户端脚本无法访问 cookie,也无法从 document.cookie 中读取并传递给 axios。

    事实上,HttpOnly cookie 比我认为的 http 请求头更安全。您需要的是在服务器端解析 auth cookie,而不是解析请求标头。

    【讨论】:

      猜你喜欢
      • 2017-08-18
      • 2021-12-23
      • 2019-04-11
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多