实施 Google 身份服务弹出代码模型时如何处理 CSRF?

How to handle the CSRF when implementing Google Identity Services popup code model?

在我的网站上,我使用 popup code model.

实现了 Google 身份服务

为了防止 CSRF 攻击,文档是这样说的:

With Popup mode, you add a custom HTTP header to your requests, and then on your server confirm it matches the expected value and origin.

这是文档中提供的弹出示例代码:

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'popup',
  callback: (response) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', code_receiver_uri, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    // Set custom header for CRSF
    xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
    xhr.onload = function() {
      console.log('Auth code response: ' + xhr.responseText);
    };
    xhr.send('code=' + code);
  },
});

我的理解是我需要在上面的代码中添加一个随机的CSRF代码字符串,然后在我的服务器上进行验证。

但是我应该把 CSRF 代码放在哪里呢?

我认为也许它应该像这样进入 code 变量 xhr.send('code=' + 'MY_CSRF_STRING') 但是当我这样做时我的 headers 看起来像这样(MY_CSRF_STRING 丢失了所以我无法在服务器上验证它):

{
   "host":"localhost:5001",
   "connection":"keep-alive",
   "accept":"*/*",
   "access-control-request-method":"POST",
   "access-control-request-headers":"x-requested-with",
   "origin":"http://localhost:8080",
   "user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36",
   "sec-fetch-mode":"cors",
   "sec-fetch-site":"same-site",
   "sec-fetch-dest":"empty",
   "referer":"http://localhost:8080/",
   "accept-encoding":"gzip, deflate, br",
   "accept-language":"en-US,en;q=0.9",
   "severity":"INFO",
   "message":"googleAuthorization req.headers"
}

如果 CSRF 代码没有放在那里,code 变量中还应该放什么?

我想我明白了。

但我仍然很想听听其他人的意见,以确保这是正确的。

简而言之,this answer 概述了 csrf 保护来自检查自定义 X-Requested-With header 是否存在。无需创造自己的独特价值。

Google 代码示例中还有一个拼写错误造成了这种混淆。

xhr.send('code=' + code); 应该是 xhr.send('code=' + response.code);。因为我们从响应中获取授权码并将其传递给服务器。