Does the Gmail API support JWT? - node.js

I want to access the Gmail API using NodeJS.
I'm using a server-to-server approach (see this) but when I execute the code below, I get a backEndError, code 500 from the Google API.
Any ideas?
var authClient = new google.auth.JWT(
'email',
'key.pem',
// Contents of private_key.pem if you want to load the pem file yourself
// (do not use the path parameter above if using this param)
'key',
// Scopes can be specified either as an array or as a single, space-delimited string
['https://www.googleapis.com/auth/gmail.readonly']
);
authClient.authorize(function(err, tokens) {
if (err)
console.log(err);
gmail.users.messages.list({ userId: 'me', auth: authClient }, function(err, resp) {
// handle err and response
if (err) {
console.log(err);
});

Yes, I have the same problem. If I use the scope "https://mail.google.com", I get
403
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
And if I use the scope "https://mail.google.com/" (notice the / at the end), I get
403
'Forbidden'
It seems to be related to using JWT and service account.

Related

Not getting user information with Google Plus sign-in api + Node.js

I have the following code snippet, to retrieve user information when he uses gmail to login:
oauth2Client.getToken(code, function(err, tokens) {
if (err) {
console.log(err);
res.send(err);
return;
}
console.log("allright!!!!");
var plus = google.plus('v1');
var API_KEY = 'AXXXXXXXXXXXXXXXXXXXXXXXXXU'; // specify your API key here
plus.people.get({
auth: API_KEY,
userId: 'me'
}, function (err, user) {
console.log(user);
});
res.send(tokens);
});
Gmail and google+ APIs are both enabled. The user object which is retrieved is returning 'null', while it should return the user information object. Why is this so? Am i giving correct value for userId? How can i retrieve information like gmail address, first name, last name, etc.
It seems you are using the client wrong, here you have an example taken from the Node.js client repo:
oauth2Client.setCredentials({
access_token: 'ACCESS TOKEN HERE',
refresh_token: 'REFRESH TOKEN HERE'
});
plus.people.get({
userId: 'me',
auth: oauth2Client
}, function (err, response) {
// handle err and response
});
You have to pass the oauth2Client instance through the auth property, not API_KEY.
Did you check the err argument? I guess you are getting null because it is returning an error, something like you did not authenticate.

users.list returns 403 Error: Not Authorized to access this resource/api

I am trying to retrieve a list of users using the node.js googleapis library and a service account.
I followed this guide to 'Perform Google Apps Domain-Wide Delegation of Authority'. There are examples for Java and Python, but unfortunately not for node.js, which seems to work rather differently.
I tried following the quickstart and completed the first two steps, but then it uses a manual OAuth flow instead of a service account.
So I tried to follow the example here to authorize using a service account. That all seems to work until I send the request, then I get an error: Error: Not Authorized to access this resource/api with code: 403.
Here's my code:
var google = require('googleapis'),
GoogleAuth = require('google-auth-library'),
authFactory = new GoogleAuth(),
admin = google.admin('directory_v1')
authFactory.getApplicationDefault(function (err, authClient) {
console.log('GOT APPLICATION DEFAULT', authClient)
if (err) {
console.log('Authentication failed because of ', err);
return;
}
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
console.log('SCOPE REQUIRED')
var scopes = ['https://www.googleapis.com/auth/admin.directory.user'];
authClient = authClient.createScoped(scopes);
}
var request = {
auth: authClient,
domain: 'mydomain.com'
};
console.log('request:', request)
admin.users.list(request, function (err, result) {
if (err) {
console.log('admin.users.list error', err);
} else {
console.log(result);
}
});
});
What have I missed please?
After several hours of experimenting I came to the conclusion that this particular API cannot be accessed with a service account. Although it is not explicitly stated in the docs anywhere that I could find, the quickstart seems to overcome this limitation by using an OAuth process and then storing in a file the tokens required to authorize future requests. If I'm wrong please add a better answer!
My solution is to use the quickstart project to generate those tokens and then add the credentials and tokens from the quickstart to my project and use them whenever my server starts, something like:
let tokens = require('./credentials/tokens.json'),
credentials = require('./credentials/oauth_credentials.json'),
clientSecret = credentials.installed.client_secret,
clientId = credentials.installed.client_id,
redirectUrl = credentials.installed.redirect_uris[0],
google = require('googleapis'),
GoogleAuth = require('google-auth-library'),
authFactory = new GoogleAuth(),
admin = google.admin('directory_v1'),
oauth2Client = new authFactory.OAuth2(clientId, clientSecret, redirectUrl);
oauth2Client.credentials = tokens;
let request = {
auth: oauth2Client,
domain: 'coachaxis.com'
};
console.log('request:', request)
admin.users.list(request, function (err, result) {
if (err) {
console.log('admin.users.list error', err);
} else {
console.log(result);
}
});
It's not elegant but it works.

How can I get a list of emails sent from a particular person?

I am using the Google Gmail API to get a list of messages. What I would like to do is get a list of all the messages that have been sent from a particular user. Here is what I have so far:
var oauth2Client = new OAuth2('', '', '');
oauth2Client.setCredentials(token);
var gmail = google.gmail('v1');
gmail.users.messages.list({
auth: oauth2Client,
userId: 'me'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
cb(null, false);
} else {
cb(null, response);
}
});
I tried setting userId: 'person#email.com' but that gave me the following error:
The API returned an error: Error: Delegation denied for person#email.com
What am I missing? Thanks ahead of time for any answers!
You should use q parameter with value like this: from:person#email.com. It would filtrate emails by from header.
Then you are trying to use userId: 'person#email.com Google API thinks that you want a list of emails from person#email.com inbox (but you do not have access to it).

Loopback - Implementing custom authentication

We are developing a REST service but we already have an infrastructure in place to manage users. But we want to leverage the authentication and authorization mechanism of Loopback. The requirement is to
Add a remote method and receive the user credentials
Manually verify the credentials through stored procedure call
Generate the access token through Loopback
Going forward use Loopback authorization mechanisms such as roles in the application
Should I be implementing a custom login service provider using Loopback's third party login support ? I couldn't find a very good resource on this area. Any pointers would be much appreciated.
Please check some of the following examples to see if it fits your use case:
https://github.com/strongloop/loopback-example-access-control
https://github.com/strongloop/loopback-example-passport
My example is using a bootscript in express but you could easily change it into a remote method.
module.exports = function(app) {
//get User model from the express app
var UserModel = app.models.User;
app.post('/login', function(req, res) {
console.log(req.body);
//parse user credentials from request body
const userCredentials = {
"username": req.body.username,
"password": req.body.password
}
UserModel.findOne({
"where": {
"username": userCredentials.username
}
}, function(err, user) {
// Custom Login - Put the stored procedure call here
if (err) {
//custom logger
console.error(err);
res.status(401).json({
"error": "login failed"
});
return;
}
// Create the accesstoken and return the Token
user.createAccessToken(5000, function(err, token) {
console.log(token)
res.json({
"token": result.id,
"ttl": result.ttl
});
})
})
});
}
Now you can use that Token for Loopbacks authorization mechanism.

Retrieve info for specific user's ID

I do my PHD work dedicated to Social Network Analysis.
As tools was selected Node JS and Facebook API
Now what I can do is retrieve user's ID's with the additional info, but to build graph I need lists of the user's friends.
I have Heroku App but I'm totally disappointed what to do with te APP_ID to get information needed to build data.
Where I should start?
There are some Node.js packages available for this purpose.
Third party SDKs for Facebook
This is very useful, in case you want to write the same code and share between your server (nodejs) and the client (FB JS-SDK)
In order to start, you need to have access_tokens from users, you want information from. (Through FB App)
FB.login(function(response) {
if (response.authResponse) {
var res = response.authResponse;
FB.api('/me', function(response) {
registerUser({ "fb_user_id": res.userID, //register user in your database
"access_token": res.accessToken
}, function() {
//handle here after registration
});
});
} else {
//handle reject in requested fields
}
}, { scope: 'email,friends_about_me'});
//you can set scope field according to your use.
Refer to this for extended profile properties that can be used in scope field.
Once you get access_tokens, you can use them with one of the third party SDK above.
For example with facebook-node-sdk,
This sdk also provides you request access_token api
var FB = require('fb');
var accessToken = FB.getAccessToken();
FB.setAccessToken(accessToken);
FB.api('idHere', { fields: ['id', 'name'] }, function (res) { //you can access fields, access_token has access to
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
return;
}
console.log(res.id);
console.log(res.name);
});
You can also use api function directly with access_token.
FB.api('me', { fields: ['id', 'name'], access_token: 'access_token' }, function (res) {
console.log(res);
}

Resources