最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeError: Cannot read property 'client_secret' of undefined - Stack Overflow

programmeradmin4浏览0评论

I'm trying to follow Google's Node API to access gmail here.

When running their sample quickstart as node quickstart.js, I am given the following error:

TypeError: Cannot read property 'client_secret' of undefined
    at authorize (/home/user/example/quickstart.js:32:43)
    at processClientSecrets (/home/example/bstick/quickstart.js:21:3)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:439:3)
  • I have downloaded the key and renamed it client_secret.json, and copied it to working directory of quickstart.js
  • node --version = 7.8.0, package.json has "google-auth-library": "^0.10.0", "googleapis": "^19.0.0"

Source code(Google's example):

var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';

// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the
  // Gmail API.
  authorize(JSON.parse(content), listLabels);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];
  var auth = new googleAuth();
  var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function(err, token) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client);
    }
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */
function getNewToken(oauth2Client, callback) {
  var authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES
  });
  console.log('Authorize this app by visiting this url: ', authUrl);
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter the code from that page here: ', function(code) {
    rl.close();
    oauth2Client.getToken(code, function(err, token) {
      if (err) {
        console.log('Error while trying to retrieve access token', err);
        return;
      }
      oauth2Client.credentials = token;
      storeToken(token);
      callback(oauth2Client);
    });
  });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
  try {
    fs.mkdirSync(TOKEN_DIR);
  } catch (err) {
    if (err.code != 'EEXIST') {
      throw err;
    }
  }
  fs.writeFile(TOKEN_PATH, JSON.stringify(token));
  console.log('Token stored to ' + TOKEN_PATH);
}

/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels(auth) {
  var gmail = google.gmail('v1');
  gmail.users.labels.list({
    auth: auth,
    userId: 'me',
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var labels = response.labels;
    if (labels.length == 0) {
      console.log('No labels found.');
    } else {
      console.log('Labels:');
      for (var i = 0; i < labels.length; i++) {
        var label = labels[i];
        console.log('- %s', label.name);
      }
    }
  });
}

I'm trying to follow Google's Node API to access gmail here.

When running their sample quickstart as node quickstart.js, I am given the following error:

TypeError: Cannot read property 'client_secret' of undefined
    at authorize (/home/user/example/quickstart.js:32:43)
    at processClientSecrets (/home/example/bstick/quickstart.js:21:3)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:439:3)
  • I have downloaded the key and renamed it client_secret.json, and copied it to working directory of quickstart.js
  • node --version = 7.8.0, package.json has "google-auth-library": "^0.10.0", "googleapis": "^19.0.0"

Source code(Google's example):

var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';

// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the
  // Gmail API.
  authorize(JSON.parse(content), listLabels);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];
  var auth = new googleAuth();
  var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function(err, token) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client);
    }
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */
function getNewToken(oauth2Client, callback) {
  var authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES
  });
  console.log('Authorize this app by visiting this url: ', authUrl);
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter the code from that page here: ', function(code) {
    rl.close();
    oauth2Client.getToken(code, function(err, token) {
      if (err) {
        console.log('Error while trying to retrieve access token', err);
        return;
      }
      oauth2Client.credentials = token;
      storeToken(token);
      callback(oauth2Client);
    });
  });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
  try {
    fs.mkdirSync(TOKEN_DIR);
  } catch (err) {
    if (err.code != 'EEXIST') {
      throw err;
    }
  }
  fs.writeFile(TOKEN_PATH, JSON.stringify(token));
  console.log('Token stored to ' + TOKEN_PATH);
}

/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels(auth) {
  var gmail = google.gmail('v1');
  gmail.users.labels.list({
    auth: auth,
    userId: 'me',
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var labels = response.labels;
    if (labels.length == 0) {
      console.log('No labels found.');
    } else {
      console.log('Labels:');
      for (var i = 0; i < labels.length; i++) {
        var label = labels[i];
        console.log('- %s', label.name);
      }
    }
  });
}
Share Improve this question edited Apr 26, 2017 at 16:31 cbll asked Apr 26, 2017 at 16:16 cbllcbll 7,21929 gold badges78 silver badges123 bronze badges 6
  • what is this line of code where the error is happening quickstart.js:32:43? – funcoding Commented Apr 26, 2017 at 16:26
  • That's in the authorize function. SPecifically: var clientSecret = credentials.installed.client_secret – cbll Commented Apr 26, 2017 at 16:27
  • ok, how's the client_secret.json is loaded? – funcoding Commented Apr 26, 2017 at 16:29
  • If you check the link in the original post, you can see their quickstart.js code. I'm updating it with the question here too. – cbll Commented Apr 26, 2017 at 16:30
  • Great! Thanks for sharing the code. Can you console.log(credentials) inside the authorize function – funcoding Commented Apr 26, 2017 at 16:36
 |  Show 1 more comment

3 Answers 3

Reset to default 8

It seems you must have selected something other than OAuth while generating the credentials.

So as per the steps your config file should look like this

{"installed": //whatever

But if u select Web, then your config file will look like this

{"web":{ //whatever

So open your config file & based on that change this line.

  var clientSecret = credentials.installed.client_secret;
//it should be credentials.whatever-key.client_secret.
//Example : If its web then this line should be credentials.web.client_secret.

2020 Update: The "Other" application type no longer exists. But the "Desktop" option provides the same result.

You have either generated the wrong type of credential (see Parth Ghiya's answer) or selected the wrong type of application.

Do the following:

  1. Go to https://console.developers.google.com/apis/credentials
    and click Create credentials button.
  2. Choose OAuth client ID option
  3. Select application type: Other
    (not Web application!)
  4. Give it a name and click Create
  5. Close popup (which shows client ID and client secret)
  6. Click the download icon on your freshly created Credential in the OAuth 2.0 client IDs list
  7. move the downloaded .json file to your project folder
  8. rename the file to client_secret.json
  9. run node quickstart.js

You should be good to go.

发布评论

评论列表(0)

  1. 暂无评论