Google 认证后的 React-Native 网络请求不携带认证 cookie

React-Native network requests after Google authentication not carrying authentication cookie

我正在将我的 iOS 应用程序从 Cordova 迁移到 React-Native。我有一个 App Engine 后端并在应用程序中使用 Google 身份验证。使用 cordova,用户只需使用 webview 登录他们的 Google 帐户,这将删除一个 cookie,然后他们可以按如下方式访问他们的数据:

function getSomeResource(callback_method)
{
     $.ajax({ 
    type: "GET",
    url: 'https://myapp.appspot.com' + '/endpoint',
    dataType: "jsonp",
    cache: true,
    xhrFields: {
      withCredentials: true
    },
    success: function(result) 
        {
            callback_method(result);
        },
    error: function(fail)
      {
         console.log(fail)
      }
    });
}

对于 React-Native,我使用的是 https://github.com/apptailor/react-native-google-signin 插件。授权工作如下:

  1. 用户点击验证 google link
  2. Safari 打开
  3. 用户验证
  4. Returns 到我的应用

并且调用下面的函数时

const user = GoogleSignin.currentUser();

提供了一个用户对象。

但是,似乎没有存储任何身份验证 cookie,因此在使用以下 RN 网络请求时,对 App Engine 后端的后续请求无法将用户识别为已登录

fetch('https://myapp.appspot.com' + '/endpoint', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Access-Control-Allow-Credentials' : 'true'
  }
})
.then((response) => response.text())
.then((responseText) => {
  var responseObject = JSON.parse(responseText);
  console.log(responseObject);
});

问题是我是否有任何方法可以获取 cookie(就像我们使用 Cordova 所做的那样),以便我可以使用它根据 GAE 后端对用户进行身份验证?

正如有人在 Facebook RN group, you can use the react-native-cookie 库中所说的那样处理这个问题。但是,我真的认为您应该重新考虑使用基于 cookie 的身份验证,并改为使用基于令牌的身份验证。

基于 Cookie 的身份验证确实只适用于 Web 应用程序。这对于 Cordova 应用程序来说很好,因为整个应用程序都在 WebView 中,但是,您需要在使用 React Native 时改变您对应用程序的看法。您应该将 RN 应用程序视为有效的原生应用程序,用 JS 编写。

GoogleSignin.currentUser() return 的对象包含一个 serverAuthCode 参数,假设您正确配置了它 (see the note here)。您可以使用它来获取用户的访问令牌。这是一些未经测试的代码:

function getTokenForUser(user) {
  var formData = new FormData();
  formData.set("grant_type", "authorization_code");
  formData.set("client_id", "{clientId}");
  formData.set("client_secret", "{clientSecret}");
  formData.set("redirect_uri","");
  formData.set("code", user.serverAuthCode);

  return fetch('https://www.googleapis.com/oauth2/v4/token', {
    method: 'POST',
    body: formData,
  }).then((response) => response.json())
}

这将 return 一个使用令牌对象解析的承诺。示例:

{
  "expires_in": 3600,
  "token_type": "Bearer",
  "refresh_token": "...",
  "id_token": "...",
  "access_token": "..."
}

然后您可以使用它来提出您需要的请求。

抱歉,我无法发表评论。 (我 post 在 Facebook RN group 编辑了这个)

感谢Dan的回答,帮了大忙! 如果有效,我也会 post 更新。