Accountmanager Auth token whithout clientID and cl

2019-07-06 14:10发布

问题:

Hello I'm retrieving a auth token on my app with that code :

private String updateToken(boolean invalidateToken, int accountref) {
    String authToken = "null";
    try {
        AccountManager am = AccountManager.get(TestAuthActivity.this);
        Account[] accounts = am.getAccountsByType("com.google");
        AccountManagerFuture<Bundle> accountManagerFuture;
        if(TestAuthActivity.this == null){//this is used when calling from an interval thread
            accountManagerFuture = am.getAuthToken(accounts[accountref], SCOPE_CONTACTS_API, false, null, null);
        } else {
            accountManagerFuture = am.getAuthToken(accounts[accountref], SCOPE_CONTACTS_API, null, TestAuthActivity.this, null, null);
        }
        Bundle authTokenBundle = accountManagerFuture.getResult();
        authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN).toString();
        if(invalidateToken) {
            am.invalidateAuthToken("com.google", authToken);
            authToken = updateToken(false, accountref);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    Dialog d = new Dialog(TestAuthActivity.this);
    d.setTitle("Token :" + authToken);
    d.show();


    return authToken;
}

And I do receive an authToken ! (though I didn't put in the clientID and clientSecret) ==> accountManagerFuture = am.getAuthToken(accounts[accountref], SCOPE_CONTACTS_API, null, TestAuthActivity.this, NULL (HERE), null); , is that token valid ?

EDIT 5/08/2012 :

here is my NEW PHP script code that is trying to use the token to get the user's ID but still gets an "invalid token" from google server :

<?php

if( isset($_POST['authToken'])){        


//curl -H 'Authorization: GoogleLogin auth="Your_ClientLogin_token"' https://www.google.com//m8/feeds/contacts/default/full


    $var = $_POST['authToken'];
    $url = "https://accounts.google.com/o/oauth2/tokeninfo?access_token='".$var."' ";       
    //$url = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token='"<?php echo rfc3986_decode($_POST['authToken'])"' ";

    //<?php echo $oauth->rfc3986_decode($accrss_token['oauth_token']) 
    // Initialize session and set URL.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);

        // Set so curl_exec returns the result instead of outputting it.
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        // Get the response and close the channel.
        $response = curl_exec($ch);
        curl_close($ch);

        echo(json_encode($response));

}
?>

The token I m getting is with the same java android code but with these 2 lines changed :

        if(TestAuthActivity.this == null){//this is used when calling from an interval thread
            accountManagerFuture = am.getAuthToken(accounts[accountref], "oauth2:https://www.googleapis.com/auth/userinfo.email", false, null, null);
        } else {
            accountManagerFuture = am.getAuthToken(accounts[accountref], "oauth2:https://www.googleapis.com/auth/userinfo.email", null, TestAuthActivity.this, null, null);
        }

and here is how I'm sending the token from my android app to my php server :

public static void createSession(Context con, String authToken) {

    String result = null;
    InputStream is = null;

    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

    nameValuePairs.add(new BasicNameValuePair("authToken", authToken));

    try {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://192.168.1.13/loginSession/authActivity4.php");
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = httpclient.execute(httppost);

        HttpEntity entity = response.getEntity();
        is = entity.getContent();

    } catch (Exception e) {
        Log.i("taghttppost", "" + e.toString());

    }

    // conversion de la réponse en chaine de caractère
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "UTF-8"));

        StringBuilder sb = new StringBuilder();

        String line = null;

        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }

        is.close();

        result = sb.toString();
    } catch (Exception e) {
        Log.i("tagconvertstr", "" + e.toString());
    }
    // recuperation des donnees json
    try {
        Log.i("tagconvertstr", "[" + result + "]");

        JSONObject jObj = new JSONObject(result);

        long userID = jObj.getLong("user_id");

        Dialog d = new Dialog(con);
        d.setTitle(String.valueOf(userID));
        d.show();

    } catch (JSONException e) {
        Log.i("tagjsonexp", "" + e.toString());
    } catch (ParseException e) {
        Log.i("tagjsonpars", "" + e.toString());
    }

}

回答1:

I can't see anything wrong with your Android code that gets the token given that you are using the token type "oauth2:https://www.googleapis.com/auth/userinfo.email" as you mentioned in the later update.

I have a test application with very similar code and when using the token type "oauth2:https://www.googleapis.com/auth/userinfo.email" I get a valid token (running Android 2.3.3 on my phone), so it should work.

To make sure the token is valid I log the token, copy it from the log and load https://accounts.google.com/o/oauth2/tokeninfo?access_token=<token> in Chrome. When I do this I get the expected response without any error.

Maybe you could test the same to narrow down where the problem might be?

Update:

This will only work as long as the initial token you got is valid, after it expires you will get an error when you try to use it. My test app stopped working after a while when the token expired. When I changed it to always invalidate the token after I receive it started working again.

For some reason calling am.invalidateAuthToken("com.google", null); doesn't invalidate the token when the token type is "oauth2:https://www.googleapis.com/auth/userinfo.email", so you must specify the token when you want to invalidate it (as your code does).

So if you make sure that you always call your updateToken() method with the invalidateToken parameter set to true this should work for you.



回答2:

This API doesn't take clientID or clientSecret as input. The AccountManager will use your saved Google credentials to get you a token by calling any needed Web APIs in the background, or return a cached token, if available. If it returned a token without error, it should be valid. Try it out.