Авторизационный токен Accountmanager без clientID и clientSecret

Здравствуйте, я получаю токен авторизации в моем приложении с этим кодом:

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;
}

И я получаю authToken! (хотя я не вставил clientID и clientSecret) ==> accountManagerFuture = am.getAuthToken(accounts[accountref], SCOPE_CONTACTS_API, null, TestAuthActivity.this, NULL (HERE), null); этот токен действителен?

РЕДАКТИРОВАТЬ 5/08/2012:

Вот мой НОВЫЙ код скрипта PHP, который пытается использовать токен для получения идентификатора пользователя, но все еще получает "недопустимый токен" с сервера Google:

<?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));

}
?>

Я получаю токен с тем же кодом java android, но с двумя измененными строками:

        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);
        }

и вот как я отправляю токен из моего приложения для Android на мой php сервер:

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());
    }

}

2 ответа

Решение

Я не вижу ничего плохого в вашем коде Android, который получает токен, если вы используете тип токена "oauth2:https://www.googleapis.com/auth/userinfo.email"как вы упомянули в последующем обновлении.

У меня есть тестовое приложение с очень похожим кодом и при использовании типа токенаoauth2:https://www.googleapis.com/auth/userinfo.email"Я получил действительный токен (на моем телефоне работает Android 2.3.3), поэтому он должен работать.

Чтобы убедиться, что токен действителен, я регистрирую токен, копирую его из журнала и загружаю https://accounts.google.com/o/oauth2/tokeninfo?access_token=<token> в хроме. Когда я делаю это, я получаю ожидаемый ответ без каких-либо ошибок.

Может быть, вы могли бы проверить то же самое, чтобы сузить, где проблема может быть?

Обновить:

Это будет работать только до тех пор, пока исходный токен, который вы получили, действителен, после его истечения вы получите ошибку при попытке его использовать. Мое тестовое приложение перестало работать через некоторое время после истечения срока действия токена. Когда я изменил его, чтобы всегда делать недействительным токен после его получения, он снова начал работать.

Почему-то звонит am.invalidateAuthToken("com.google", null); не делает недействительным токен, когда тип токена "oauth2:https://www.googleapis.com/auth/userinfo.emailmsgstr ", поэтому вы должны указать токен, если хотите его аннулировать (как это делает ваш код).

Поэтому, если вы убедитесь, что всегда вызываете свой метод updateToken() с параметром invalidateToken, установленным в значение true, это должно сработать для вас.

Этот API не принимает clientID или clientSecret в качестве входных данных. AccountManager будет использовать ваши сохраненные учетные данные Google, чтобы получить токен, вызвав все необходимые веб-API в фоновом режиме, или вернет кэшированный токен, если он доступен. Если он вернул токен без ошибок, он должен быть действительным. Попробуйте это.

Другие вопросы по тегам