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 插件。授权工作如下:
- 用户点击验证 google link
- Safari 打开
- 用户验证
- 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 更新。
我正在将我的 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 插件。授权工作如下:
- 用户点击验证 google link
- Safari 打开
- 用户验证
- 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 更新。