Android 正确实施AccountManager、oauth-2和过期令牌

Android 正确实施AccountManager、oauth-2和过期令牌,android,oauth,token,accountmanager,Android,Oauth,Token,Accountmanager,我与AccountManager和OAuth-2斗争了一段时间,我已经实现了AccountManager(带有服务和帐户验证器)、webview的登录活动等。 当用户在webview上输入其凭证时,我实现了所有oauth-2流,并将访问令牌保存为AccountManager密码。 我现在知道的最后一件事是,当我向服务器发出http请求时,如何正确地实现流,它的响应是Json with {"message":"access_token_is_expired","error":true....}

我与AccountManager和OAuth-2斗争了一段时间,我已经实现了AccountManager(带有服务和帐户验证器)、webview的登录活动等。 当用户在webview上输入其凭证时,我实现了所有oauth-2流,并将访问令牌保存为AccountManager密码。 我现在知道的最后一件事是,当我向服务器发出http请求时,如何正确地实现流,它的响应是Json with

{"message":"access_token_is_expired","error":true....}
所以我应该阅读这个响应,分析它,并使用resh令牌执行另一个请求,以获得另一个访问令牌。 如何正确地实现这一点?哪里在哪个班? 可能是我的验证器。getAuthToken方法应该改进吗? 代码如下:

@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
        String authTokenType, Bundle loginOptions) throws NetworkErrorException {
    Log.v(TAG, "getAuthToken()");

    if (!authTokenType.equals(Const.AUTHTOKEN_TYPE)) {
        final Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");
        return result;
    }

    final AccountManager am = AccountManager.get(mContext);
    final String auth_token = am.getPassword(account);
    if (auth_token != null) {
        final Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, Const.ACCOUNT_TYPE);
        result.putString(AccountManager.KEY_AUTHTOKEN, auth_token);
        return result;
    }

    final Intent intent = new Intent(mContext, LoginActivity.class);
    intent.putExtra(Const.KEY_SERVER, am.getUserData(account, Const.KEY_SERVER));
    //intent.putExtra(LoginActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
    final Bundle bundle = new Bundle();
    bundle.putParcelable(AccountManager.KEY_INTENT, intent);
    return bundle;
}


为了理解这一点,我做了大量的工作,但我失败了。

几天后,由于网络信息的幸运,我阅读了github上的代码并做了一些研究。为了帮助像我这样的人:

可以在上面的getAuthToken方法中重新请求过期的令牌,但要在Bundle(loginoOptions)中添加应该从服务器重新请求的信息(例如,“forceReauth”=true) 我在方法中检查此参数并询问方法(上面代码的第二个和平),否则我使用通常的流

第二件重要的事情——我在这里看到的一行代码 上帝保佑汤姆G(我不能给他投一票,因为我的名声太好了)。代码行
在getAuthToken之前使用invalidateAuthToken为我做了一切。如果你觉得这有用的话,请给他投我一票。

几天后,由于网络信息的幸运,我在github上阅读了代码并做了一些研究。为了帮助像我这样的人:

可以在上面的getAuthToken方法中重新请求过期的令牌,但要在Bundle(loginoOptions)中添加应该从服务器重新请求的信息(例如,“forceReauth”=true) 我在方法中检查此参数并询问方法(上面代码的第二个和平),否则我使用通常的流

第二件重要的事情——我在这里看到的一行代码 上帝保佑汤姆G(我不能给他投一票,因为我的名声太好了)。代码行 在getAuthToken之前使用invalidateAuthToken为我做了一切。如果你觉得这有用的话,给他投我一票

 @Override
protected JSONObject doInBackground(Void... params) {
        InputStream is = null;
        try {                
            String url = "...";
            URL obj = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) obj.openConnection();                
            conn.setRequestMethod("POST");
            conn.setDoOutput(true); 
            String urlParameters = "access_token=" + mToken;
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();
            conn.connect(); 
            int response_code = conn.getResponseCode();
            is = conn.getInputStream();
            String str_response = NetworkUtilities.readStreamToString(is, 500);

            JSONObject response = new JSONObject(str_response);
            return response;


        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }