Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT Error #461

Closed
dav92lee opened this issue Aug 4, 2015 · 16 comments
Closed

JWT Error #461

dav92lee opened this issue Aug 4, 2015 · 16 comments
Assignees
Labels
🚨 This issue needs some love. triage me I really want to be triaged.

Comments

@dav92lee
Copy link

dav92lee commented Aug 4, 2015

Hello,

I am currently getting the error:

{ [Error: Not Found]
code: 404
errors: [ { domain: 'global', reason: 'notFound', message: 'Not Found' } ] }

When trying to use the calendar api using JWT. I am struggling to find this error message and how to debug this online. Please help! My code is the following:

jwtClient.authorize(function(err, tokens) {
  if (err) {
    console.log(err);
    return;
  }

  // Make an authorized request to list Drive files.
  calendar.events.list({ 
    auth: jwtClient,
    calendarId: calendarId,
    timeMin: (new Date()).toISOString(),
    maxResults: 100,
    singleEvents: true,
    orderBy: 'startTime' 
  }, function(err, resp) {
    // handle err and response
    console.log("===============")
    console.log(err)
    console.log(resp)
  });
});

The call works when i authorize via auth.OAuth2...

@nonumber1989
Copy link

Recently i use jwt based the example , What i have is a json file generated from google credential(service account)

{
  "private_key_id": "REDACTED",
  "private_key": "-----BEGIN PRIVATE KEY-----REDACTED-----END PRIVATE KEY-----\n",
  "client_email": "REDACTED@developer.gserviceaccount.com",
  "client_id": "REDACTED.apps.googleusercontent.com",
  "type": "service_account"
}

I put the private key the one file named key.pem

var authClient = new google.auth.JWT(
    'REDACTED@developer.gserviceaccount.com',
    './server/key.pem',
    'REDACTED',
    ['https://www.googleapis.com/auth/drive.readonly'],
    // User to impersonate (leave empty if no impersonation needed)
    'REDACTED.apps.googleusercontent.com');

but

keyFile---./server/key.pem
[Error: error:0906D06C:PEM routines:PEM_read_bio:no start line]

I have google a lot , but still have no solution , Could you help with this ?

Steven Xu

@dav92lee
Copy link
Author

Hmm.. I suspect it is how you are generating your .pem file. It seems like the format of it is not what the client is expecting.

@jmdobry
Copy link
Contributor

jmdobry commented Mar 4, 2016

@nonumber1989 Please for your sake, don't post your private keys on GitHub! I redacted them from your comment.

If you're using a .json key file, then your JWT code might look like this:

var google = require('googleapis');
var key = require('/path/to/key.json');

var authClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  [/**scopes go here*/],
  null
);

authClient.authorize(function (err, tokens) {
  // do something
});

Closing as this does not appear to be an issue. If you are convinced that this is really a bug, please feel free to re-open the issue and add more information such as:

  • Expected behavior
  • Actual behavior
  • Code samples
  • Version numbers
  • References docs or other links

Or, consider opening a Pull Request.

Otherwise, support questions are handled on Stack Overflow. Ask a question on Stackoverflow

@jmdobry jmdobry closed this as completed Mar 4, 2016
@kunokdev
Copy link

kunokdev commented Sep 11, 2016

I am trying to fetch all emails under our domain. I have all admin rights anda I created service account with Domain wide delegation. This is my code:

const google = require('googleapis');
const gmail = google.gmail('v1');
const directory = google.admin('directory_v1');
const scopes = [
  'https://www.googleapis.com/auth/gmail.readonly',
  'https://www.googleapis.com/auth/admin.directory.user.readonly'
];
const key = require('./service_key.json');

var authClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  scopes,
  null
);

authClient.authorize(function(err, tokens){
  if (err) {
    console.log(err);
    return;
  }

  directory.users.list(
    {
      auth: authClient,
      customer: 'my_customer',
      maxResults: 250,
      orderBy: 'email'
    }, (err, resp) => {
    if (err) {
      console.log(err);
      return;
    }

    console.log(resp);
  })

})

and I still get error

{ Error: Domain not found.
    at Request._callback (/home/kunok/code/sampleApi/node_modules/google-auth-library/lib/transporters.js:85:15)
    at Request.self.callback (/home/kunok/code/sampleApi/node_modules/google-auth-library/node_modules/request/request.js:198:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (/home/kunok/code/sampleApi/node_modules/google-auth-library/node_modules/request/request.js:1057:14)
    at emitOne (events.js:101:20)
    at Request.emit (events.js:188:7)
    at IncomingMessage.<anonymous> (/home/kunok/code/sampleApi/node_modules/google-auth-library/node_modules/request/request.js:1003:12)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
  code: 404,
  errors: 
   [ { domain: 'global',
       reason: 'notFound',
       message: 'Domain not found.' } ] }

@dfahlander
Copy link

dfahlander commented Oct 5, 2016

Getting the same error as @kunokdev even though having authorized my client for 'https://www.googleapis.com/auth/admin.directory.user' in the admin console at https://admin.google.com.

@yoyeung
Copy link

yoyeung commented Jun 16, 2017

@kumikoda @dfahlander do you find a solution to fix the error?
I have the same issue..but i am not sure is it related to the library.
I will try python.

@kunokdev
Copy link

kunokdev commented Jun 16, 2017

@yoyeung can you show example code where you are getting error and what kind of authorization do you want to achieve at the end? This library works fine, some things are just easy to misunderstand or less popular examples are hard to find.
In my case I had issues with scopes. Make sure your scopes in code match with scopes in admin page.
This is my file for authorizing users inside our domain. I use this auth to fetch user emails and their account info with my automatic scripts on the server.

// auth.js

const key = require('../service_key.json')
const Google = require('googleapis'),
const scopes = [
        'https://www.googleapis.com/auth/gmail.readonly',
        'https://www.googleapis.com/auth/admin.directory.user.readonly',
        'https://www.googleapis.com/auth/admin.directory.group'
      ]


module.exports.jwt = (email) => {
  return new Promise((resolve, reject)=>{
    let authClient = new Google.auth.JWT(
      key.client_email,
      key,
      key.private_key,
      scopes,
      email
    )
    authClient.authorize((err, tokens) => {
      if (err) {
        console.error(err);
        process.exit(1)
      }
      resolve(authClient)
    })
  })
}

Resolved object is used as auth param in your API calls. Make sure you always use 'me' as param for user id, because auth object is actually param that detects which user is authorized.

@yoyeung
Copy link

yoyeung commented Jun 16, 2017

@kunokdev here you are.

var google = require('googleapis');
var directory = google.admin('directory_v1');
var key = require('./service-account.json');
var scopes = 
    ['https://www.googleapis.com/auth/admin.directory.user',
     'https://www.googleapis.com/auth/admin.directory.user.readonly',
     'https://www.googleapis.com/auth/admin.directory.group.readonly',
     'https://www.googleapis.com/auth/admin.directory.group'];
var authClient = new google.auth.JWT(
    key.client_email,
    key,
    key.private_key,
    scopes,
    null);

authClient.authorize(function (err, tokens) {
  if (err) {
    return console.log(err);
  }
  console.log('working');
  directory.groups.list({
    auth: authClient,
    userKey: mail
  },function (err, resp) {
    // handle err and response
    if (err) {
      return console.log('err',err);
    }
    console.log(resp);
  });

});

this is the response

[ { domain: 'global',
       reason: 'notFound',
       message: 'Domain not found.' } ] }

@kunokdev
Copy link

kunokdev commented Jun 16, 2017

@yoyeung ,
This is my method for getting list of users:

// users.js

// @input: auth object
// @output: array of users
module.exports.fetch = function(auth){
  return new Promise((resolve, reject)=>{
    let params = {
        auth,
        customer: 'my_customer',
        maxResults: 100
    }
    directory.users.list(params, (err, res)=>{
      err ? reject(err)
          : resolve(res.users)
    })
  })
}

and this is how I use it with auth method from above:

const auth = require('../modules/auth.js')
const users = require('../modules/users.js')

auth.jwt('myname@mydomain.com')
.then(users.fetch)

Can you check if you are giving it proper params? User email I give it is email of admin user.

Btw, reason why is last param exposed to be param to give is because of reusability for other types of auths.

@yoyeung
Copy link

yoyeung commented Jun 16, 2017

@kunokdev
Thx for you reply.
But what is the auth.jwt('myname@mydomain.com') is?

For my case...this email is not an admin user.

@kunokdev
Copy link

kunokdev commented Jun 16, 2017

@yoyeung

This is method for authorizing users, see comment above (it's file where something gone wrong, probably). I added filenames before code, so you know which file is which.

The reason why I expose last param is because of reusability, because in our domain we have multiple admins and each has different rights.

So basically this is method from comment above, (module.exports.jwt) which returns promise that resolves auth object which you pass in further API call methods.

@yoyeung
Copy link

yoyeung commented Jun 16, 2017

@kunokdev Finally i find the issue.
it's because missing a setting in https://developers.google.com/admin-sdk/directory/v1/guides/delegation
They missing to mention the config in create Service account to click to Enable Domain-Wide Delegation
Luckily i go to php tutorial page and see this config.
So god save me. Thanks
screen shot 2017-06-16 at 5 47 52 pm

Also thanks for ur help. it's working well!!!!
Thx

@kunokdev
Copy link

kunokdev commented Jun 16, 2017

@yoyeung

that's great! It's like I mentioned above:

This library works fine, some things are just easy to misunderstand or less popular examples are hard to find.

@vimalprakashts
Copy link

vimalprakashts commented Jan 20, 2018

I am still facing this issue.

let google = require('googleapis');
let privatekey = require("./oauth2test-d48d715ddb90");
var googleAuth = require('google-auth-library');

// configure a JWT auth client
let jwtClient = new google.auth.JWT(
    privatekey.client_email,
    null,
    privatekey.private_key, [
        'https://www.googleapis.com/auth/admin.directory.user'
    ]);
//authenticate request
jwtClient.authorize(function (err, tokens) {
    if (err) {
        console.log(err);
        return;
    } else {
        console.log(tokens);

        listUsers(jwtClient);
        console.log("Successfully connected!");
    }
});

function listUsers(auth) {

    var service = google.admin('directory_v1');
    service.users.list({
        auth: auth,
        customer: 'my_customer',
        maxResults: 100,
        orderBy: 'email'
    }, function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }
        var users = response.users;
        if (users.length == 0) {
            console.log('No users in the domain.');
        } else {
            console.log('Users:');
            for (var i = 0; i < users.length; i++) {
                var user = users[i];
                console.log(user);
                console.log('%s (%s)', user.primaryEmail, user.name.fullName);
            }
        }
    });
}

I enabled the Admin SDK in my app, and enabled the "Enable Google Apps Domain-wide Delegation." for my service account, added scopes in "Manage API client access" section as well.

I if use the authorisation_code flow with my admin credentials it works fine, if I use the service account I am getting error.

The API returned an error: Error: Domain not found

@vimalprakashts
Copy link

found working example : https://stackoverflow.com/a/47241705/1124447

@aheld
Copy link

aheld commented Jan 7, 2019

The 'domain not found' error can also happen if you do not select a user to impersonate for the service account call.

const {auth, admin} = require('google-auth-library');

async function main() {

  const subject = 'user@yourDomain.com'
  
  const client = await auth.getClient({
    scopes: ['https://www.googleapis.com/auth/admin.directory.group']
  })

  //impersonate the users for whom you want to see the groups, or something like admin@yourdomain.com

  client.subject = subject    // <-- DO THIS

  const url = `https://www.googleapis.com/admin/directory/v1/groups?userKey=${subject}` //&maxResults=10`
  const res = await client.request({ url })
  console.log(res.data);
}

main().catch(console.error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚨 This issue needs some love. triage me I really want to be triaged.
Projects
None yet
Development

No branches or pull requests

9 participants