在Android应用上获取ID令牌并在后端服务器上验证它(如何使用ID令牌?)

时间:2017-01-11 18:33:56

标签: android firebase firebase-authentication

我正在开发一个Android应用程序,它使用来自我自己的REST API服务器的数据。我想使用Firebase身份验证,因为它允许用户以非常简单的方式使用Google,Facebook,Twitter ...进行登录。

但我不确定如何使用ID令牌:

  • 因为ID令牌有截止日期,我应该在客户端应用程序的每个请求上调用getToken方法,所以我确定我每次都发送一个有效的令牌吗?
  • 每次收到客户端应用程序的请求时,我应该在服务器中调用verifyIdToken吗?

我不知道这些方法(getToken和verifyIdToken)是做什么的,并且因为它们是异步的,我担心他们在每次调用时都会向Firebase服务器发出请求。所以我认为在我的每个请求中向Firebase服务器发出2个请求是不可能的......

5 个答案:

答案 0 :(得分:13)

getToken()和VerifyIdToken()都可以为每个传出/传入请求调用。

1)虽然getToken()是异步的,但Firebase Android SDK实际上会将当前Firebase用户令牌缓存在本地存储中。只要缓存的令牌仍然有效(即自发出后一小时内),getToken()立即返回令牌。只有当缓存的令牌过期时,SDK才会从远程Firebase服务器获取新令牌。

2)VerifyIdToken()也针对性能进行了优化。它缓存Firebase令牌公共证书(有效期为6小时),用于验证本地计算机上的令牌签名。除下载公共证书外,不涉及RPC。

答案 1 :(得分:8)

每次不再有效时刷新令牌。是的,您应该每次都在服务器端验证令牌。如果不再有效,则发送401错误代码并显示错误消息(如果需要)。刷新令牌时使用验证令牌,并且令牌附加到每个请求。如果您使用OkHttp,您可以创建一个拦截器,在每个请求的头中添加令牌,并且当错误代码为401时也可以刷新令牌。

答案 2 :(得分:2)

POST https://YOUR_AUTH0_DOMAIN/delegation
Content-Type: 'application/json'
{
  "client_id":       "YOUR_CLIENT_ID",
  "grant_type":      "urn:ietf:params:oauth:grant-type:jwt-bearer",
  "refresh_token":   "your_refresh_token",
  "api_type":        "app"
}

答案 3 :(得分:1)

根据您在问题中解释的内容,我猜您正在谈论使用Google登录进行跨客户端资源访问。特别是您似乎有兴趣获取Id令牌一次并使用它而无需在每个后续获取API调用。

这或多或少与离线访问机制同义。 在离线访问中,客户端I.e. Android应用程序要求对请求的范围进行用户授权。授权后,auth服务器返回一个短期授权代码,而不是发出访问令牌,该代码可用于生成访问令牌和刷新令牌。

然后,客户端可以通过安全连接将授权代码传递给后端。后端服务器可以检索作者令牌并刷新令牌并将其存储在安全位置。访问令牌是短暂的,可用于短时间访问作用域资源,并使用刷新令牌不时刷新。刷新令牌不会过期,但可以撤消。如果撤销,服务器应用程序应该要求客户端应用程序重新获取作者代码。

请仔细阅读此链接,详细说明完整的基础架构以及客户端和服务器应用程序应遵循的步骤 - https://developers.google.com/identity/protocols/CrossClientAuth

现在提出您的问题,您应该使用稍微不同的API来获取身份验证代码。看看这个API - https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.Builder.html#requestServerAuthCode(java.lang.String)

示例代码 - https://developers.google.com/identity/sign-in/android/offline-access

答案 4 :(得分:-1)

在您的应用程序类中使用以下代码,regId是您的设备令牌的值持有者。

private void checkPlayService() {
    // Check device for Play Services APK. If check succeeds, proceed with
    // GCM registration.
    if (checkPlayServices()) {
     GoogleCloudMessaging googleCloudMessaging = GoogleCloudMessaging.getInstance(activity);
        regId = getRegistrationId();

        if (TextUtils.isEmpty(regId)) {
            registerInBackground();
        }
    } else {
        Log.i(TAG, "No valid Google Play Services APK found.");
    }
}

private String getRegistrationId() {
    String registrationId = sp.getString(Consts.PROPERTY_REG_ID, "");
    if (TextUtils.isEmpty(registrationId)) {
        Log.i(TAG, "Registration not found.");
        return "";
    }
    // Check if app was updated; if so, it must clear the registration ID
    // since the existing regID is not guaranteed to work with the new
    // app version.
    int registeredVersion = sp.getInt(PROPERTY_APP_VERSION,0);
    int currentVersion = getAppVersion();
    if (registeredVersion != currentVersion) {
        Log.i(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

private void registerInBackground() {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            try {
                if (googleCloudMessaging == null) {
                    googleCloudMessaging = GoogleCloudMessaging.getInstance(activity);
                }

                regId = googleCloudMessaging.register(Consts.PROJECT_NUMBER);
                msg = "Device registered, registration ID=" + regId;
                Log.e("GCMID",msg);
                storeRegistrationId(regId);

            } catch (IOException ex) {
                msg = "Error :" + ex.getMessage();
            }
            return msg;
        }

        @Override
        protected void onPostExecute(String msg) {
            Log.i(TAG, msg + "\n");
        }
    }.execute(null, null, null);
}



private void storeRegistrationId(String regId) {
    int appVersion = getAppVersion();
    Log.i(TAG, "Saving regId on app version " + appVersion);
    sp.edit().putString(Consts.PROPERTY_REG_ID, regId).commit();
    sp.edit().putInt(PROPERTY_APP_VERSION, appVersion).commit();
}