How to access GMail API from my own GMail?

964 Views Asked by At

If I try to call the GMail API, I get the following error in return:

{
    "error": {
        "errors": [{
            "domain": "global",
            "reason": "failedPrecondition",
            "message": "Bad Request"
        }],
        "code": 400,
        "message": "Bad Request"
    }
}

First I generate a token

var sHead = JSON.stringify({
    "alg": "RS256",
    "typ": "JWT"
});
var iat = timeStampf();
var exp = iat + 3600;
var sPayload = JSON.stringify({
    "iss": client_email,
    "sub": client_email,
    "scope": "https://mail.google.com/",
    "aud": "https://www.googleapis.com/oauth2/v3/token",
    "exp": exp,
    "iat": iat
});
var sJWS = KJUR.jws.JWS.sign("RS256", sHead, sPayload, private_key);
var paramstoken = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + sJWS


getToken("POST", "/oauth2/v3/token", paramstoken, jsonData, replier);
/*rest petition
return 200 ok {
    "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
    "token_type": "Bearer",
    "expires_in": 3600
}
*/

Next I test the token

function testToken(accessToken, replier) {
    var client = vertx.createHttpClient().host(urlbase).port(443).ssl(true).maxPoolSize(10);
    var request = client.request("GET", "/gmail/v1/users/me/messages", function(resp) {
        console.log('server returned status code: ' + resp.statusCode());
        console.log('server returned status message: ' + resp.statusMessage());
        resp.bodyHandler(function(body) {
            replier(JSON.parse(body.toString()));
        });
    });
    request.headers()
        .set("Content-type", contentType)
        .set("Authorization", "Bearer " + accessToken);
    request.end();
    client.close();
}

And I get an error 400 bad request in return. But if I use a different scope, for example Google+, I get a 200 ok.

I think the error is '"sub":client_email'. I tried add more GMails in the Google console, and with 3 mails auto create for the project, only the mail from Json return me failed precondition if try with others mails including auto created for project and my own GMail(the GMail owner of project) error is 401 unautorized_client.

Or do I need other "grant_type Use the following string, URL-encoded as necessary: urn:ietf:params:oauth:grant-type:jwt-bearer"?

[email protected]
[email protected]///this is de mail downloaded in json from credentials
[email protected]

(this is server side js)

2

There are 2 best solutions below

3
On BEST ANSWER

The problem seems with your OAauth credentials. On Google Developer Console -> Credentials, when you try to get new credentials, there are 3 options, 1) Web Application (This is the one you should be using) 2) Service Account (Which is I believe you are trying to use right now), 3) Installed Application (For iOS & Android apps)

Also while authenticating, mention that you will be trying to access the service content in 'offline' mode, which will give you a 'refresh Token' to make subsquent requests without user's involvment.

You are able to access Google+ because its public data as compared to Gmail where you are trying to access messages for a certain user (Private data). Service account credentials will not give you access to a user's private data and you must impersonate the user whose emails you are trying to access via authentication using Web Application credentials in your case.

Hope this helps....

3
On
"sub": client_email

seems to be incorrect.

You should use your gmail address in the sub field, as you are trying to impersonate this email address.