你的做法会给你firebase id令牌,见here。
您会在 firebase 中遇到三种类型的令牌:
-
Firebase ID 令牌
由 Firebase 在用户登录 Firebase 应用时创建。这些令牌是经过签名的 JWT,可以安全地识别 Firebase 项目中的用户。这些令牌包含用户的基本个人资料信息,包括用户的 ID 字符串,该字符串对于 Firebase 项目是唯一的。因为可以验证 ID 令牌的完整性,您可以将它们发送到后端服务器以识别当前登录的用户。
-
身份提供者令牌
由联合身份提供商(例如 Google 和 Facebook)创建。这些令牌可以有不同的格式,但通常是 OAuth 2.0 访问令牌。 Firebase 应用使用这些令牌来验证用户是否已成功通过身份提供者进行身份验证,然后将其转换为 Firebase 服务可用的凭据。
-
Firebase 自定义令牌
由您的自定义身份验证系统创建,允许用户使用您的身份验证系统登录 Firebase 应用。自定义令牌是使用服务帐户的私钥签名的 JWT。 Firebase 应用使用这些令牌的方式与使用联合身份提供商返回的令牌非常相似。
现在,你得到的是 firebase Id 令牌,你需要的是身份提供者令牌。
获取身份提供者令牌很简单,它只是您显示的步骤的前一步。
所以,提到了我们使用 firebase 登录 google 的方式here。
我将在下面添加在 UI 中显示一个按钮的完整代码,点击该按钮后,用户将登录到 Google 帐户。然后我将获取 google 访问令牌,然后将其发送到 firebase,然后将其转换为 firebase 令牌 ID。
我想你已经配置了安卓应用进行谷歌登录,如果没有,你可以详细了解here。
(简而言之,如果您已经完成设置,请查看下面的第 5 步。)
代码:
-
配置 Google SignIn 和 GoogleApiClient:
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// NOTE :
// The string passed to requestIdToken, default_web_client_id,
// can be obtained from credentials page (https://console.developers.google.com/apis/credentials).
// There mentioned Web application type client ID is this string.
// ...
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* Activity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
-
将 Google 登录按钮添加到您的应用中
<com.google.android.gms.common.SignInButton
android:id="@+id/sign_in_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
-
设置登录点击监听器
findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() {
public void onClick(View v){
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
});
-
在 Activity 中重写 OnActivityResult 方法:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account); // This method is implemented in step 5.
} else {
// Google Sign In failed, update UI appropriately
// ...
}
}
-
使用 Google SignInAccount 进行 Firebase 身份验证
String idTokenString = "";
...
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "Google User Id :" + acct.getId());
// --------------------------------- //
// BELOW LINE GIVES YOU JSON WEB TOKEN, (USED TO GET ACCESS TOKEN) :
Log.d(TAG, "Google JWT : " + acct.getIdToken());
// --------------------------------- //
// Save this JWT in global String :
idTokenString = acct.getIdToken();
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
if(task.isSuccessful()){
// --------------------------------- //
// BELOW LINE GIVES YOU FIREBASE TOKEN ID :
Log.d(TAG, "Firebase User Access Token : " + task.getResult().getToken());
// --------------------------------- //
}
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
else {
Log.w(TAG, "signInWithCredential", task.getException());
Toast.makeText(GoogleSignInActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
-
最后一步:为 Firebase 验证侦听器
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
// ...
}
};
// ...
}
//...
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
因此,您的答案在于第 5 步,即在您通过 Firebase 身份验证之前以及您在 google 登录之后进行身份验证。
希望对你有帮助!
更新:
重要的是,在步骤 1 中,您请求令牌 ID,否则在步骤 5 中,您将获得空令牌 ID。有关更多信息,请参阅here。我已更新第 1 步。
更新:
根据讨论,检索到的令牌是 JWT 令牌,如 here 所写。我们需要的是谷歌访问令牌。下面的代码使用 JWT 令牌在 OAuth 后端触发并检索此访问令牌:
(注意:我用的是okhttp 2.6.0版本,其他版本可能有不同的方法)
代码:
...
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormEncodingBuilder()
.add("grant_type", "authorization_code")
.add("client_id", "<Your-client-id>") // something like : ...apps.googleusercontent.com
.add("client_secret", "{Your-client-secret}")
.add("redirect_uri","")
.add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8") // device code.
.add("id_token", idTokenString) // This is what we received in Step 5, the jwt token.
.build();
final Request request = new Request.Builder()
.url("https://www.googleapis.com/oauth2/v4/token")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(final Request request, final IOException e) {
Log.e(LOG_TAG, e.toString());
}
@Override
public void onResponse(Response response) throws IOException {
try {
JSONObject jsonObject = new JSONObject(response.body().string());
final String message = jsonObject.toString(5);
Log.i(LOG_TAG, message);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
这是具有所需访问令牌的输出:
I/onResponse: {
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "1\/xz1eb0XU3....nxoALEVQ",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA",
"access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4"
}
希望现在有帮助!