我正在使用此库https://github.com/devfd/react-native-google-signin/使用react-native构建Google签名流。
lib工作得很好,我可以成功登录谷歌,但我们需要离线访问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'
]
})
从这里我们得到了来自lib的正确回复,其中包括:
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
的错误。
此时我不知道还需要改变什么。也许有人知道这里发生了什么。
答案 0 :(得分:2)
好的,我找到了解决方案。而且非常简单。
当您使用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);
}
});
});
}
答案 1 :(得分:0)
我的解决方案: 在php服务器上
public static function userCodeTokenExchange($code,$device_type = "browser"):\Google_Client { $client = new \Google_Client(); $client->setAuthConfig(app_path('client_secrets.json')); switch ($device_type){ case "ios": break; case "android": break; case "browser": $client->setRedirectUri(url("/")); break; case "server": $client->setRedirectUri(getenv('GOOGLE_REDIRECT_URI')); break; default: throw new \Exception("Invalid device request."); break; } $client->setAccessType("offline"); $tokenRequest = $client->fetchAccessTokenWithAuthCode($code); $client->setAccessToken($tokenRequest); return $client; }