我正在构建Android应用,并且正在尝试将Google Books API集成到我的应用中。 现在,登录工作。我收到了同意屏幕,其中包含访问我帐户中的Google图书数据的请求。 我现在正尝试使用以下代码从我的库中获取所有书架:
public class GetUsernameTask extends AsyncTask<String, Void, Void> {
Activity mActivity;
String mScope;
String mEmail;
public GetUsernameTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
/**
* Executes the asynchronous job. This runs when you call execute()
* on the AsyncTask instance.
*/
@Override
protected Void doInBackground(String... params) {
try {
String token = fetchToken();
if (token != null) {
Log.i("TAG", "Got a token: " + token);
// Use the token to access the user's Google data.
String api_key = params[0];
URL object = new URL("https://www.googleapis.com/books/v1/mylibrary/bookshelves?key=" + api_key);
HttpsURLConnection connection = (HttpsURLConnection) object.openConnection();
connection.setRequestProperty("Authorization", token);
connection.setRequestMethod("GET");
connection.setDoInput(true);
Log.i("TAG", connection.getResponseMessage());
InputStream is = connection.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
Log.i("TAG", line);
}
}
} catch (IOException e) {
Log.e("TAG", "Got an exception", e);
}
return null;
}
/**
* Gets an authentication token from Google and handles any
* GoogleAuthException that may occur.
*/
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present
// so we need to show the user some UI in the activity to recover.
Log.i("TAG", "Nu! more exceptions", userRecoverableException);
} catch (GoogleAuthException fatalException) {
// Some other type of unrecoverable exception has occurred.
// Report and log the error as appropriate for your app.
Log.i("TAG", "Nu! more exceptions", fatalException);
}
return null;
}
}
此代码来自Google文档(https://developers.google.com/android/guides/http-auth)。
作为请求,我附加了“?key = api_key”,由文档(https://developers.google.com/books/docs/v1/using?hl=en#WorkingMyBookshelves)指定,我也在标题中指定了我的令牌。打印令牌时,它看起来像这样:xxxx.YQJ8nJimB8eeQOIdVkkg2WfkobsBkARzc2TWJL4d_2ipIQuJ4U9uFTvNNhye7i0474TbsA
我得到的回报令人惊讶;这是一个401 HTTP错误,即以下内容:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
作为API密钥,我尝试使用以下内容:
我还发现我的硬盘上有两个debug.keystore文件,一个在C:\ Android \中,另一个在〜\ .android中。我只是决定将两个SHA-1哈希值添加到两个Android密钥(以及OAuth 2.0客户端ID),希望它以某种方式使用其他密钥库 - 无济于事。
我做错了什么?
我也尝试过使用Google Play服务库。这会产生不同的错误;但仍然存在错误。
我使用此代码(在doInBackground方法中)尝试使用所述API:
try {
Books service = new Books.Builder(AndroidHttp.newCompatibleTransport(), JacksonFactory.getDefaultInstance(), null).setGoogleClientRequestInitializer(new BooksRequestInitializer(api_key)).build();
List<Bookshelf> shelves = service.mylibrary().bookshelves().list().execute().getItems();
}catch (Exception ex){
Log.e("TAG", "Error while using Books", ex);
}
使用Android密钥,我收到403 Forbidden HTTP响应,并显示消息“您的API密钥上配置了每IP或每个Referer限制,并且请求与这些限制不匹配。请使用Google Developers如果允许来自此IP或引用者的请求,则更新API密钥配置的控制台。“但是,我没有看到使用Android API密钥的任何IP限制。
使用服务器密钥,我收到400 Bad Request,可能是因为该令牌丢失了。
我做错了什么?我错过了什么?
答案 0 :(得分:1)
在询问了一些与我关系密切的人之后,我注意到了我设置Authorization标头的方式。根据Wiki(https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side),令牌前面有一个&#34; Type&#34;。对于Google OAuth2,此类型为Bearer
。
因此,改变
connection.setRequestProperty("Authorization", token);
进入
connection.setRequestProperty("Authorization", "Bearer " + token);
做了这个伎俩。编辑:显然,这是在这里指定的:https://developers.google.com/books/docs/v1/using?hl=en#query-params - 一直在页面底部的标题下,我觉得不适合这么重要的事情。
对于Google API,我现在意识到我没有在任何地方指定令牌。搜索了一下之后,我发现你可以像这样设置Oauth标记:
List<Bookshelf> shelves = service.mylibrary().bookshelves().list().setOauthToken(token).execute().getItems();
这给了我想要的结果。请注意:这是使用服务器键完成的,而不是Android键。 Android密钥仍然给我403 ipRefererBlocked错误。