axios跨域请求使用凭证以及默认xsrfCookieName和xsrfHeaderName的坑

axios跨域请求遇到的坑
在与服务端沟通跨域头问题时发现,服务器设置跨域头的问题:

先只设置了

Access-Control-Allow-Origin ’xxxxxx.com‘,

首先正常发起一个请求,结果接口返回
user token not present,很明显,跨域请求的时候需要使用凭证。

所以前端在请求配置加上如下参数:

    withCredentials: true, // `withCredentials` 表示跨域请求时是否需要使用凭证

结果没有 返回 user token not present了,

此时 接口的response Headers  如下

    Access-Control-Allow-Credentials: false
    Access-Control-Allow-Headers: Content-Type
    Access-Control-Allow-Methods: GET
    Access-Control-Allow-Origin: https://www.xxx.com
    Connection: keep-alive
    Content-Length: 45
    Content-Type: text/javascript;charset=utf-8
    Date: Wed, 04 Sep 2019 11:20:22 GMT
    Server: nginx
    X-Powered-By: Express
    X-Traceid: -8289785987636653913

 

但是出现另外的问题,提示服务端没有设置Access-Control-Allow-Credentials 为true

然后又要 服务端加了

'Access-Control-Allow-Credentials' 'true'; 

之后发现响应头如下:

    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: Content-Type
    Access-Control-Allow-Methods: GET
    Access-Control-Allow-Origin: https://www.xxx.com
    Connection: keep-alive
    Content-Length: 45
    Content-Type: text/javascript;charset=utf-8
    Date: Wed, 04 Sep 2019 11:20:22 GMT
    Server: nginx
    X-Powered-By: Express
    X-Traceid: -8289785987636653913

然后又发现另外的问题:

控制台报错:Access to XMLHttpRequest at ‘…….’ has been blocked by CORS policy: Request header field x-xsrf-token is not allowed by Access-Control-Allow-Headers in preflight response.

字面意思是请求头Access-Control-Allow-Headers设置问题。

不过要先搞明白x-xsrf-token 到底怎么回事:

先查看axios的官方文档发现了这个

  // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
  xsrfCookieName: 'XSRF-TOKEN', // default

  // `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
  xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的

但官方文档这个注释说的不是很明白,这里解释下:
axios请求配置对象中提供了 xsrfCookieName 和 xsrfHeaderName这两个属性,其中 xsrfCookieName 表示存储 token 的 cookie 名称,xsrfHeaderName 表示请求 headers 中 token 对应的 header 名称。然后每次发送请求的时候,会自动从 cookie 中读取对应的 token 值,然后将其添加到请求 headers中。

检查了一下cookie,发现确实存在名为XSRF-TOKEN的cookie,同时,在请求头中发现了X-XSRF-TOKEN:xxxxxxx;也就是说请求头已经带上了这个X-XSRF-TOKEN,但是服务器不认识。
这是因为服务端跨域头设置中没有设置 Access-Control-Allow-Headers  : x-csrf-token

Access-Control-Allow-Headers  x-csrf-token

看来Access-Control-Allow-Headers上还要加上一个 x-csrf-token

最后我想是不是要求服务端加上下面的配置就可以了

'Access-Control-Allow-Headers' 'Content-Type, x-csrf-token, X-Access-Token, Accept'; 

但是,服务端不支持配置这个x-csrf-token,这个也是有原因的,服务不需要通过header验证用户凭证而是通过saturn,所以服务端是不需要在请求头上带这个x-csrf-token的。axios默认加的这个xsrfHeaderName:X-XSRF-TOKEN,这个X-XSRF-TOKEN服务端没有配置,就会出现上述问题,导致请求失败。

那么最终结论就是被axios的默认配置坑了,在这种情况下我们就不能使用axios设置的xsrfHeaderName 和 xsrfCookieName 默认值了。

处理方案就是在axios中将 默认值设置为空即可:

   
   axios.defaults.xsrfCookieName = '' // 必须设置
   axios.defaults.xsrfHeaderName = '' // 可以不设置,后者依赖前者
也可以在具体请求的配置中设置这两个为空。
   
    axios({
      method: 'get', 
      url: url, 
      xsrfCookieName: ''
    })

总结一下:对于axios而言,xsrfCookieName 和 xsrfHeaderName 其实是可以不用设置的,在服务端api不需要从header中获取token的情况下我们不需要设置。但是单单只设置 xsrfHeaderName 为空时却也是不行的,根据axios给的官方解释,应该是只要设置axios.defaults.xsrfCookieName = ”,后面xsrfHeaderName的这个设置不设置其实就不重要了。

ps:axios 具体配置:https://www.kancloud.cn/yunye/axios/234845
ps:服务端跨域头设置包含如下这些,具体的设置的值,要根据前后端业务需要来设置。

发表评论

记录工作生活点滴。

返回
顶部