Android 中有效的 google 帐户 OAuth 2 令牌

Posted

技术标签:

【中文标题】Android 中有效的 google 帐户 OAuth 2 令牌【英文标题】:Valid google account OAuth 2 token in Android 【发布时间】:2012-04-05 04:56:07 【问题描述】:

我对 Google 帐户 OAuth 2 令牌有疑问。 我们需要令牌来访问帐户信息(数字 ID、电子邮件、用户名) 在 AccountManager 中请求 getAuthToken(account, SCOPE, options, mContext, getAuthTokenCallback, null) 后,token 无法访问账户信息。 HTTP请求的响应https://www.googleapis.com/plus/v1/people/me(标头“授权:OAuth ya29.AHES6ZSuMvL3FoxqXfevYevWyEmTPOE1HXW7_Tj6l3UAN-2J7kTs0-I”)


    "error": 
    "errors": [
        
         "domain": "usageLimits",
         "reason": "dailyLimitExceededUnreg",
         "message": "Daily Limit Exceeded. Please sign up",
         "extendedHelp": "https://code.google.com/apis/console"
        
    ],
    "code": 403,
    "message": "Daily Limit Exceeded. Please sign up"
    

为什么会出现这个错误? 以前使用由空格分隔的两种类型的 AuthSub 令牌。(SCOPE_OLD_PERMITIONS) 现在它不起作用并导致 java.io.IOException

如何获取有效令牌?

这是获取令牌的请求:

TCGoogleAccountsManager mng = new TCGoogleAccountsManager(this);
mng.requestAccountOAuthToken(this, acc);

帮助获取令牌的类:

public class TCGoogleAccountsManager 
private static final String CLIENT_SECRET = ...;
private static final String CLIENT_ID = ...;
private static final String SCOPE_CONTACTS_API = "cp";
private static final String SCOPE_android_API = "android";
private static final String SCOPE_GOOGPE_PLUS = "oauth2:https://www.googleapis.com/auth/plus.me";
private static final String SCOPE_MY_INFO = "oauth2:https://www.googleapis.com/auth/userinfo.email";
private static final String SCOPE_OLD_PERMITIONS = "oauth2:https://www-opensocial.googleusercontent.com/api/people/ oauth2:https://www.googleapis.com/auth/userinfo#email";
private static final String SCOPE = SCOPE_GOOGPE_PLUS;
private static final String COM_GOOGLE = "com.google";

private AccountManager mManager;
private OnGetOAuthTokenRequestCompletedListener mTokenRequestListener;

public TCGoogleAccountsManager(Context ctx) 
    mManager = AccountManager.get(ctx.getApplicationContext());
    mTokenRequestListener = new GoogleTokenListener(
            ctx.getApplicationContext());


public int getAccountsNumber() 
    return mManager.getAccountsByType(COM_GOOGLE).length;


public Account[] getGoogleAccounts() 
    return mManager.getAccountsByType(COM_GOOGLE);



public Account getGoogleAccountByName(String name) 
    Account foundAcc = null;
    if (name != null && !name.equals("")) 
        Account[] googleAccounts = mManager.getAccountsByType(COM_GOOGLE);
        for (int i = 0; i < googleAccounts.length; i++) 
            if (name.equals(googleAccounts[i].name)) 
                foundAcc = googleAccounts[i];
                break;
            
        
    
    return foundAcc;



public Account getGoogleAccount(int index) 
    return getGoogleAccounts()[index];


public void requestAccountOAuthToken(Activity mContext, Account account) 
    try 
        final Bundle options = new Bundle();
        options.putString("client_id", CLIENT_ID);
        options.putString("client_secret", CLIENT_SECRET);
        mManager.getAuthToken(account, SCOPE, options, mContext,
                getAuthTokenCallback, null);
     catch (Exception e) 
        e.printStackTrace();
    



private AccountManagerCallback<Bundle> getAuthTokenCallback = new AccountManagerCallback<Bundle>() 
    public void run(AccountManagerFuture<Bundle> future) 
        try 
            final Bundle result = future.getResult();
            final String accountName = result
                    .getString(AccountManager.KEY_ACCOUNT_NAME);
            final String authToken = result
                    .getString(AccountManager.KEY_AUTHTOKEN);
            boolean success = (accountName != null && authToken != null);
            if (!success) 
                if (mTokenRequestListener != null) 
                    mTokenRequestListener.onRequestCompleted(false,
                            accountName, authToken);
                
             else 
                // refresh token. We need fresh token.
                mManager.invalidateAuthToken(COM_GOOGLE, authToken);
                mManager.getAuthToken(getGoogleAccountByName(accountName),
                        SCOPE, false, getAuthTokenCallbackInvalidated, null);
            
         catch (Exception e) 
            e.printStackTrace();
        
    
;


private AccountManagerCallback<Bundle> getAuthTokenCallbackInvalidated = new AccountManagerCallback<Bundle>() 
    public void run(AccountManagerFuture<Bundle> future) 
        try 
            final Bundle result = future.getResult();
            final String accountName = result
                    .getString(AccountManager.KEY_ACCOUNT_NAME);
            final String authToken = result
                    .getString(AccountManager.KEY_AUTHTOKEN);
            boolean success = (accountName != null && authToken != null);
            if (mTokenRequestListener != null)
                mTokenRequestListener.onRequestCompleted(success,
                        accountName, authToken);
         catch (Exception e) 
            e.printStackTrace();
        
    
;

感谢和问候。

【问题讨论】:

【参考方案1】:

您需要一个用于 OAuth2 的 client_id,您可以通过在 https://code.google.com/apis/console 注册您的应用程序来获取它

【讨论】:

以上是关于Android 中有效的 google 帐户 OAuth 2 令牌的主要内容,如果未能解决你的问题,请参考以下文章

Android 中多个 Google 数据 API 的单个 google 帐户 authtoken

空指针异常 - Android 中 Google 帐户的 GoogleAuthUtil 身份验证

在我的 Android 应用中验证 Google 帐户的最佳工作流程是啥?

在 Android 中使用 Google/Facebook 时的 Firebase Auth 重复帐户

如何在使用 Google 登录按钮时不将 Google 帐户添加到 Android 手机

如何从 google plus 帐户中注销 google plus 在 android 中的集成