【问题标题】:AccountManager: invalidateAuthToken does not invalidate the tokenAccountManager:invalidateAuthToken 不会使令牌失效
【发布时间】:2012-09-13 11:01:50
【问题描述】:

我正在尝试从存储在 Android 设备中的 Google 帐户获取全新的令牌,但我得到的只是我在过去几天缓存的旧令牌。好像是缓存在手机某处,连上网请求都没有发送(我在没有上网的情况下在app里做了测试,返回的是同一个token)。

在从AccountManagerFuture 获得带有getResult 的新方法之前,我使用了invalidateAuthToken 方法。请看:

public String updateToken(Activity activity) throws Exception {             
    AccountManager am = AccountManager.get(activity);
    Account[] accounts = am.getAccountsByType("com.google");

    if (accounts == null || 
        accounts.length == 0 || 
        "".equals(accounts[0].name.trim())) 
    {
        throw new Exception("Não há contas Google configuradas no smartphone.");
    } 
    else if (!"crsilva@gmail.com".equals(accounts[0].name.trim()) && 
             !"cristiano.bezerra@sulamerica.com.br".equals(accounts[0].name.trim()) &&
             !"tholiver@gmail.com".equals(accounts[0].name.trim())) 
    {
        Log.w("Util.updateToken","conta obtida: " + accounts[0].name);
        throw new Exception("Conta Google não autorizada.");
    }
    Log.w("Util.updateToken","conta obtida: " + accounts[0].name);
    am.invalidateAuthToken("com.google", null);
    Log.w("Util.updateToken","Passou do invalidateAuthToken");
    AccountManagerFuture<Bundle> future = 
        am.getAuthToken(accounts[0], "ah", null, activity, null, null);
    Log.w("Util.updateToken","Passou do getAuthToken");
    Bundle bundle = future.getResult();
    Log.w("Util.updateToken","Passou do getResult");
    future = null;
    am = null;
    accounts = null;
    String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    Log.w("Util.updateToken","Token: " + authToken);
    return authToken;
}

一个线程通过单例实例从 Util 类调用此方法。清单具有所有必要的权限。有人知道为什么令牌没有刷新吗?

【问题讨论】:

    标签: java access-token accountmanager


    【解决方案1】:

    简单地“窥视”当前缓存的令牌,检查它是否仍然有效,并在需要时创建一个新令牌更简单。

    String authToken = accountManager.peekAuthToken(account, Constants.AUTHTOKEN_TYPE);
    // validate the token, invalidate and generate a new one if required
    accountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authToken);
    accountManager.blockingGetAuthToken(account,
                    Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);
    

    【讨论】:

    • 根据 peekAuthToken 的文档,这只能由帐户的 Authenticator(或共享相同 UID 的其他人)使用:“此方法要求调用者持有权限 AUTHENTICATE_ACCOUNTS 并拥有与帐户的身份验证器相同的 UID。”。所以它不可能用于谷歌帐户
    • 正如@nibarius 提到的 - 这会引发 java.lang.SecurityException: uid XXXX cannot peek the authtokens associated with account of type: com.google
    【解决方案2】:

    要使身份验证令牌无效,您需要将要使其无效的令牌作为第二个参数传递给 invalidateAuthToken。请参阅this blog post 的“4.4.3 使身份验证令牌无效”部分。该页面上的视频也很有帮助。

    invalidateAuthToken 的文档提到第二个参数可能为 null,但这仅表示允许使用 null 调用此方法,而不是如果传递 null,则每个缓存的令牌都无效。

    如果你这样做,你的代码应该可以工作:

    // Get token
    AccountManagerFuture<Bundle> future = am.getAuthToken(accounts[0], "ah", null, activity, null, null);
    Bundle bundle = future.getResult();
    String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    
    // invalidate the token since it may have expired.
    am.invalidateAuthToken("com.google", authToken);
    
    // Get token again
    future = am.getAuthToken(accounts[0], "ah", null, activity, null, null);
    bundle = future.getResult();
    authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 2012-01-21
      • 1970-01-01
      相关资源
      最近更新 更多