Google Books API 403 Access Not Configured

不羁的心 提交于 2019-12-11 04:03:42

问题


I'm trying to contact the Google Books API and perform a title search, which only requires a public API key and no OAUTH2. All I get is the following error:

{
    "error": {
        "errors": [
        {
            "domain": "usageLimits",
            "reason": "accessNotConfigured",
            "message": "Access Not Configured"
        }
        ],
        "code": 403,
        "message": "Access Not Configured"
    }
}

After having googled around for hours, it seems many others have the same problem but with other Google APIs. What I've done so far:

  1. Registered a project in my Developer Console
  2. Enabled the Books API
  3. Signed my application to get the SHA1 certificate number
  4. Chosen to get a public API key for Android in my Developer Console
  5. Pasted the following string into the public API key form, in order to get the key: "SHA1 number;com.package", without quotes
  6. Copy pasted the generated key into my code.

The code looks as follows:

private void callGoogleBooks(){
    String key = MY_KEY;
    String query = "https://www.googleapis.com/books/v1/volumes?q=flowers+inauthor:keyes&key=" + key;
    Log.d("google books", callApi(query));
}

public String callApi(String query){
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet getRequest = new HttpGet(query);
    HttpResponse httpResponse = null;

    try{
        httpResponse = httpClient.execute(getRequest);
    } catch(UnsupportedEncodingException e){
        Log.d("ERROR", e.getMessage());
    } catch(ClientProtocolException e){
        Log.d("ERROR", e.getMessage());
    } catch (IOException e){
        Log.d("ERROR", e.getMessage());
    }

    if(httpResponse != null){
        try{
            HttpEntity httpEntity = httpResponse.getEntity();
            InputStream is = httpEntity.getContent();
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(is, "utf-8"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while((line = br.readLine()) != null){
                sb.append(line + "\n");
            }
            is.close();
            String responseString = sb.toString();
            return responseString;
        } catch (Exception e){
            Log.d("ERROR", e.getMessage());
        }
    }
    return null;
}
  • Are there any obvious errors? Do I need to format or package my request differently?
  • Do I need to add anything to the manifest file?
  • When specifying the package when generating the public API key, do I need to specify the same package name as in my app structure? I read somewhere that it has to be unique, but changing it to something less likely to be a duplication resulted in the same error.

The error apparently has to do with "usageLimits", but I'm not even close to 1% of the 1000 calls allowed per day in my test project.

I've also tried to implement the Google Books Java Sample without using the code above, getting the same error message. I've also tried disabling and re-enabling the Books API, without any luck.

Thanks in advance.


回答1:


This worked for me

String link = "https://www.googleapis.com/books/v1/volumes?q="+params;
InputStream is = null;
try 
{
    int timeoutConnection = 10000;
    URL url = new URL(link);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setConnectTimeout(timeoutConnection);
    con.setReadTimeout(timeoutConnection);
    con.setRequestProperty("key", "API_KEY");
    if(con.getResponseCode() != HttpURLConnection.HTTP_OK){
        publishProgress("Error conneting.");
    }
    is=con.getInputStream();
}

from this thread: Google Books API for Android - Access Not Configured




回答2:


Problem is when setting up your API key restriction for android app, you specified the package name and SHA-1 certificate fingerprint. Therefore your API key will only accept request from your app with package name and SHA-1 certificate fingerprint specified.

So how google know that request's sent FROM YOUR ANDROID APP? You MUST add your app's package name and SHA certificate in the header of each request with following keys:

Key: "X-Android-Package", value: your app package name

Key: "X-Android-Cert", value: SHA-1 certificate of your apk

FIRST, get your app SHA signature (you will need Guava library):

/**
 * Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests
 *
 * @param packageName Identifies the APK whose signature should be extracted.
 * @return a lowercase, hex-encoded
 */
public static String getSignature(@NonNull PackageManager pm, @NonNull String packageName) {
    try {
        PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        if (packageInfo == null
                || packageInfo.signatures == null
                || packageInfo.signatures.length == 0
                || packageInfo.signatures[0] == null) {
            return null;
        }
        return signatureDigest(packageInfo.signatures[0]);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
}

private static String signatureDigest(Signature sig) {
    byte[] signature = sig.toByteArray();
    try {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        byte[] digest = md.digest(signature);
        return BaseEncoding.base16().lowerCase().encode(digest);
    } catch (NoSuchAlgorithmException e) {
        return null;
    }
}

Then, add package name and SHA certificate signature to request header:

java.net.URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {
    connection.setDoInput(true);
    connection.setDoOutput(true);

    connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
    connection.setRequestProperty("Accept", "application/json");

    // add package name to request header
    String packageName = mActivity.getPackageName();
    connection.setRequestProperty("X-Android-Package", packageName);
    // add SHA certificate to request header
    String sig = getSignature(mActivity.getPackageManager(), packageName);
    connection.setRequestProperty("X-Android-Cert", sig);
    connection.setRequestMethod("POST");

    // ADD YOUR REQUEST BODY HERE
    // ....................
} catch (Exception e) {
    e.printStackTrace();
} finally {
    connection.disconnect();
}

Hope this help! :)



来源:https://stackoverflow.com/questions/20926166/google-books-api-403-access-not-configured

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!