0

我正在尝试在 Java 中获取 android 设备上的访问令牌。

首先,我在Google API Console中为已安装的应用程序(Android)创建了客户端 ID ,并设置了将请求访问令牌的包和SHA1 指纹

正如我在OAuth2ForDevices中所读到的,要获得访问令牌,我必须首先获得一个用户代码。所以我尝试使用Aquery发送带有 client_id 和范围的 POST 请求,如下所示:

AQuery aq = new AQuery(activity);
         aq.ajax("https://accounts.google.com/o/oauth2/device/code?" +
                "scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile" +
                "client_id=xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
            JSONObject.class,new AjaxCallback<JSONObject>(){

           @Override
           public void callback(String url, JSONObject traffic_flow, AjaxStatus status) {

               publishProgress(traffic_flow.toString());

           }
    });

问题是它JSONObject traffic_flow总是空的。我也尝试使用它来获取它(但我不认为这是正确的方法):

authToken = GoogleAuthUtil.getToken(activity, mEmail,  "audience:server:client_id:xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com");

其中 mEmail 是来自 android 设备的电子邮件,但我得到了GoogleAuthException“未知”。如何正确获取用户代码?

编辑:

我终于能够使用以下方法获得身份验证令牌:

String scope = "audience:server:client_id:xxxxxxxxxxxx.apps.googleusercontent.com";
String token = GoogleAuthUtil.getToken(activity, client.getAccountName(), scope);

其中范围是在Google API 控制台中生成的 Web 应用程序的客户端 ID (之后我将令牌发送到我的网站并对其进行验证),客户端是 PlusClient(更多内容请参见Google+ 入门)。

我已经在我的测试应用程序中获得了令牌,现在的问题是,当我想将代码包含到我的新应用程序中时,我又遇到了那个丑陋的异常:

com.google.android.gms.auth.GoogleAuthException: Unknown at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)

这些应用程序的所有客户端 ID 都在同一个项目中,清单中的权限应该是 ok ( GET_ACCOUNTS,USE_CREDENTIALS,AUTHENTICATE_ACCOUNTS,INTERNET,ACCESS_NETWORK_STATE)。我在新应用程序中所做的唯一更改是在创建 PlusClient 时设置范围,因为没有它就无法工作(不知道为什么在我的测试应用程序中没有它就可以工作)

mPlusClient = new PlusClient.Builder(this, this, this)
            .setVisibleActivities("http://schemas.google.com/AddActivity")
            .setScopes(Scopes.PLUS_LOGIN, Scopes.PLUS_PROFILE)
            .build()

我错过了什么?

4

2 回答 2

1

这是我用于获取 OAuth 2.0 令牌以与 Google Coordinate api 一起使用的代码,我在 ASyncTask 中运行它。我没有包含生成 DESIRED_USER 的部分,因为它在某些 AccountManager 意图上使用 startActivityForResult()。希望你可以使用这个。

你应该用你的替换SCOPE,我认为应该是oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile

import android.accounts.Account;
import android.accounts.AccountManager;

final String SCOPE = "oauth2:https://www.googleapis.com/auth/coordinate";
AccountManager accountManager = AccountManager.get(context);
//Kill Current token
accountManager.invalidateAuthToken("com.google",authManager.getToken());
//Fetch userAccount
Account userAccount = null;
for(Account account : accountManager.getAccounts())
    if(account.name.equals(DESIRED_USER))
    {
        try {
            return accountManager.blockingGetAuthToken(userAccount, SCOPE, false);
        } catch (Exception e) {
            System.out.println("Error: "+e.toString());
            e.printStackTrace();
        }
    }
return null;
于 2013-08-01T17:05:12.250 回答
1

如果您必须使用此 API,那么您应该使用 POST 版本的 AQuery 并正确传递 POST 参数,如下所示。此 API OAuth2ForDevices适用于资源受限的设备,用户可以通过另一种方式授权您的应用。

params.put("scope", "your scopes");
params.put("client_id", "your client id");

AQuery aq = new AQuery(activity);
aq.ajax("https://accounts.google.com/o/oauth2/device/code", params, JSONObject.class, 
  new AjaxCallback<JSONObject>() {
           @Override
           public void callback(String url, JSONObject traffic_flow, AjaxStatus status) {
               publishProgress(traffic_flow.toString());
           }
});

但是,如果您的要求是在具有常规输入功能的 Android 手机上使用常规 OAuth2,那么 Android 的标准 OAuth 机制就是this

于 2013-07-29T22:01:08.633 回答