Access Google Drive API with refresh token, no bro

2019-05-18 09:51发布

问题:

I am trying to access GoogleDrive API (my own a/c) using the refresh token --issued from OAuth Playground -- like below. I am using my refresh token and access token for offline access but I am getting a 401 unauthorized. My code is based on reference belwoand google-api javadocs recommendation for building an offline request

I do not wish to use a browser, i wish to run this from a server side app to upload to my own a/c.

ref: http://stackoverflow.com/questions/10533203/fetching-access-token-from-refresh-token-using-java

Code:

public static void main(String[] args) throws IOException {
        HttpTransport TRANSPORT = new NetHttpTransport();
        JsonFactory JSON_FACTORY = new JacksonFactory();

        String refreshTokenString="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //from console

        String accessTokenString ="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; //from console

        GoogleCredential credential = createCredentialWithRefreshToken(
            TRANSPORT, JSON_FACTORY, new TokenResponse().setRefreshToken(refreshTokenString));
    credential.setAccessToken("accessTokenString");


    //exeucute HTTP request for offline accessTokenString

    // Execute HTTP GET request to revoke current token.
    HttpResponse response = TRANSPORT.createRequestFactory()
            .buildGetRequest(new GenericUrl(
                    String.format(
                            "https://www.googleapis.com/drive/v2/changes",
                            credential.getAccessToken()))).execute();

    System.out.println("RESPONSE: " +response);

}

 public static GoogleCredential createCredentialWithRefreshToken(HttpTransport transport,
                                                                    JsonFactory jsonFactory, TokenResponse tokenResponse) {

    HttpTransport TRANSPORT = new NetHttpTransport();
    JsonFactory JSON_FACTORY = new JacksonFactory();
    return new GoogleCredential.Builder().setTransport(transport)
            .setJsonFactory(JSON_FACTORY)
            .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
            .build()
            .setFromTokenResponse(tokenResponse);
}

And the error:

    {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Login Required",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Login Required"
 }
}

I am using a valid refresh token and access token (works from playground console) but i get login required 401 here when running from Java app. I requires this for daily backups from server directly to Drive.

回答1:

You can't use the access or refresh token from the Playgorund in your application. These tokens where issued by google only to be used in the playground. The tokens you get are tied to a Client Id and Client Secret. Obviously your CLIENT_ID and CLIENT_SECRET are different from the ones which are used by the Google Playground application.

You really need your application to request these tokens, so for the first time you need a browser, so that the user can accept that YOUR app (not Google Playground) is getting your information stored at google. This is called "user consent", and shown in the little diagram at this page: Using OAuth 2.0 for Web Server Applications)

Then, when you have the refresh token for your application. You don't need the browser any more for your daily backups. You can use your code with a valid refresh token for your app, as presented in your post.



回答2:

Can I access using the refresh token only as this does not expire?

No. You must convert the refresh token to an access token.