我正在使用此库使用react-native构建谷歌签名流程https://github.com/devfd/react-native-google-signin/.
该库运行良好,我可以成功使用谷歌登录,但我们需要请求离线访问 api,对于网络应用程序,我们使用此流程。 https://developers.google.com/identity/sign-in/web/server-side-flow。
对于网络来说效果很完美,但是当我们尝试在本机应用程序上执行相同的操作时,我们使用react-native lib中的配置。
GoogleSignin.configure({
webClientId: 'the client id of the backend server',
iosClientId: 'the client id of the application',
offlineAccess: true,
forceConsentPrompt: true,
scopes: [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/pubsub'
]
})
从中我们得到了来自库的正确响应,其中包括:
serverAuthCode: <one-time token to access Google API from the backend on behalf of the user>
但是当我们尝试交换该代码时:
const google = require('googleapis');
const OAuth2 = google.auth.OAuth2;
const oauth2Client = new OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
'postmessage'
);
export function getToken (code: string): Promise<any> {
return new Promise((resolve, reject) => {
oauth2Client.getToken(code, (err, tokens) => {
if (!err) {
resolve(tokens);
} else {
reject(err);
}
});
});
}
我总是得到
redirect_uri_mismatch
或invalid_grant
的错误。
此时我不知道我还需要改变什么。也许有人知道这里发生了什么。
好的,我找到了解决方案。而且非常简单。
当您使用 ServerAuthCode 来兑换用户令牌时,您需要将后端的返回 URI 设置为 null。
这就是我最后使用 getToken 方法所做的事情。现在一切都很顺利!
export function getToken (code, typeOf = 'web') {
const redirectUri = (typeOf === 'movil') ? null : 'postmessage';
const oauth2Client = new OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
redirectUri
);
return new Promise((resolve, reject) => {
oauth2Client.getToken(code, (err, tokens) => {
if (!err) {
resolve(tokens);
} else {
reject(err);
}
});
});
}
我的解决方案: 在 PHP 服务器上
公共静态函数 userCodeTokenExchange($code,$device_type = "browser"):\Google_Client { $client = new \Google_Client(); $client->setAuthConfig(app_path('client_secrets.json')); 开关($device_type){ 案例“ios”: 休息; 案例“安卓”: 休息; 案例“浏览器”: $client->setRedirectUri(url("/")); 休息; 案例“服务器”: $client->setRedirectUri(getenv('GOOGLE_REDIRECT_URI')); 休息; 默认: throw new \Exception("无效的设备请求。"); 休息; } $client->setAccessType("离线"); $tokenRequest = $client->fetchAccessTokenWithAuthCode($code); $client->setAccessToken($tokenRequest); 返回$客户端; }
检查您是否有在 GoogleSignin.configure 中使用的包含 iosClientId 和 webClientId 的 .env 文件。 这对我来说是个问题