我正在尝试获取Google Refresh令牌,问题是我在任何地方都没有看到我的当前情况,我要完成的工作是从google已经生成的用户身份验证令牌中获取刷新令牌。从本机android应用程序登录,基本上,我要求我在该应用程序上需要的所有google权限,并从登录中获取auth代码,然后将该身份验证代码发送至Firebase函数后端,在那里我尝试获取刷新令牌,但我总是从Google处获得invalid_grant,所以我不知道该在哪里搞砸
我看到离线请求oauth可能会解决问题,但是我正在android应用中登录,因此我无法从后端离线请求登录,我需要登录和身份验证仅在android应用程序,我需要它通过后端发出Google助手请求,为此,唯一缺少的是刷新令牌
我从Google云控制台获取了我的google oauth2密钥,并且客户端已初始化
var OAuth2 = google.auth.OAuth2;
var _client_id = require('./config/secrets/omni.json').installed.client_id;
var _client_secret = require('./config/secrets/omni.json').installed.client_secret;
var redirect = require('./config/secrets/omni.json').installed.redirect_uris[1];
return new OAuth2(
_client_id,
_client_secret,
redirect
);
最后尝试获取令牌:
function getRefreshToken(authCode, idFBUser) {
return new Promise((resolve, reject) => {
getOAuthClient().getToken(authCode, function(err, token) {
if (!err) {
console.log(`Get Token success, token: ${token}`);
getOAuthClient().setCredentials(token);
saveRefreshFirebase(idFBUser, token)
resolve(token);
} else {
console.log("Get Token error", err);
reject(err);
}
});
});
}
我得到的错误恰恰是这个错误:{error:'invalid_grant',error_description:'Bad Request'}
我在android应用中用来请求身份验证代码的方法是这样的:
创建GoogleSignIn实例
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.requestId()
.requestIdToken(getClientId())
.requestServerAuthCode(getClientId())
.requestScopes(ASSISTANT_SCOPE)
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
调用登录意图:
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, RESULT_GOOGLE_SIGNIN)
处理登录结果:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
RESULT_GOOGLE_SIGNIN -> {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
task.result?.let { account ->
val id = account.id
val idToken = account.idToken
val authCode = account.serverAuthCode
Log.d("GoogleSignIn", "ID: $id")
Log.d("GoogleSignIn", "ID Token: $idToken")
Log.d("GoogleSignIn", "Auth code: $authCode")
btnLogin.text = "Sign Out"
loggedIn = true
} ?: Log.e("GoogleSignIn", "Exception: ${task.exception}")
} catch (e: Exception) {
Log.e("GoogleSignIn", "Catch Exception: $e")
}
}
}
}
}
而authCode是我用来尝试在后端获取Refresh Token的代码。
答案 0 :(得分:0)
您需要致电
.requestServerAuthCode(getClientId(),true)
代替
.requestServerAuthCode(getClientId())
如果要获取刷新令牌。您发布的javascript代码可以使用刷新令牌。
这是认证应用程序的最简单方法,因为所有其他种类的令牌都将过期。刷新令牌不会过期。 Google登录库为您提供了用于获取刷新令牌的访问代码。您需要保存此刷新令牌并将其发送给Google,以获得访问令牌。然后,最终可以将访问令牌用于发出API请求。
顺便说一句,这实际上是“离线访问”所指的。还花了我一点时间来弄清楚这个问题。