1

我想将以下代码转换为使用 Promise。它正在工作并在活动目录中输出用户的属性。

var client = ldap.createClient({
  url: ldap_url
});

client.bind(ldap_username, ldap_password, function (err) {
    client.search(ldap_dn_search, opts, function (err, search) {
        search.on('searchEntry', function (entry) {
          var user = entry.object;
          // It is working!!!. It outputs all user attributes.
          console.log(user);
        });

    });
}); 

以下是我的尝试,但它不输出任何内容。

var Promise = require('promise');
var client_bind = Promise.denodeify(client.bind);
var client_search = Promise.denodeify(client.search);

client_bind(ldap_username, ldap_password)
.then(function(err){
  client_search(ldap_dn_search, opts)
    .then(function(search){
      var search_on = Promise.denodeify(search.on);
      search_on('searchEntry')
        .then(function(entry){
          var user = entry.object;

          // It doesn't output anything !!!
          console.log(user);
        });
      });

    });
4

4 回答 4

5

我有同样的问题。搜索会发出事件,因此我们需要一些东西来处理它们并沿着链进一步传递。这是一段代码,对我有用:

var ldap = require('ldapjs');
var promise = require('bluebird');

var client = ldap.createClient({url: app.settings['ldap']['server']});
var uid;

promise.promisifyAll(client);

function searchPromise(res, notfoundtext) {
  return new Promise(function(resolve, reject) {
    var found = false;
    res.on('searchEntry', function(entry) {
      found = true;
      resolve(entry);
    });
    res.on('error', function(e) {
      reject(e.message);
    });
    res.on('end', function() {
      if (!found) {
        reject(notfoundtext);
      }
    });
  });
}

client.searchAsync(app.settings['ldap']['baseDn'], {filter: '(mail='+credentials.email+')', scope: 'sub'})
  .then(function(res) {
    return searchPromise(res, 'User isn\'t exists.');
  })
  .then(function (entry) {
    uid = entry.object.uid;
    return client.bindAsync(entry.object.dn, credentials.password);
  })
  .then(function() {
    return client.searchAsync('cn='+app.settings['ldap']['group']+',cn=groups,'+app.settings['ldap']['baseDn'], {scope: 'sub', filter: '(memberUid='+uid+')'});
  })
  .then(function(res) {
    return searchPromise(res, 'User is not in group ' + app.settings['ldap']['group']);
  })
  .then(function() {
    console.log('All is ok');
  })
  .catch(function(message) {
    console.log('Error:' + message);
  });

在搜索之后,我立即添加了一个步骤来捕获事件、处理它们并沿着链进一步传递。这使得函数 searchPromise。

祝你编码好运)

于 2016-03-01T18:28:07.993 回答
0

很可能这些方法确实需要client作为上下文调用,因此在将bind()它们传递给之前需要它们Promise.denodeify

var client_bind = Promise.denodeify(client.bind.bind(client));
var client_search = Promise.denodeify(client.search.bind(client));

此外,正确使用 Promise 应该是这样的:

client_bind(ldap_username, ldap_password).then(function() {
    return client_search(ldap_dn_search, opts);
//  ^^^^^^ always return something from the callback
}).then(function(search) { // flatten your chain
    return Promise.denodeify(search.on).call(search, 'searchEntry');
//                                    ^^^^^^ an alternative to `bind`
}).then(function(entry){
    var user = entry.object;
    console.log(user);
}).catch(function(err) { // always catch errors!
    console.error(err);
});
于 2015-06-06T15:58:28.953 回答
0

我在这里遇到了同样的问题,但我通过添加承诺解决了它,并在不使用bluebird的情况下解决了响应,这是我的代码的一个例子:

async getLdapUser(username: any): Promise<any> {
    let myPromise = new Promise<boolean>((resolve, reject) => {
      console.log('ssssssssss', username);
      const adSuffix = 'OU=xxxx,OU=xxxxx,DC=xxxxxxx,DC=xxxxxx'; 
      const password = 'xxxxxxxxxxxxx';
      // Create client and bind to AD
      const client = ldap.createClient({
        url: 'ldap://1.1.1.1:389',
      });
      // promise.promisifyAll(client);
      let resp = false;
      // console.log(client);
      client.bind('userTest', password,(err: any) => {
        console.log('RESP', resp);
        if (err) {
          console.log('Error in new connetion ' + err);
        } else {
          /*if connection is success then go for any operation*/
          console.log('Success');
          const searchOptions: {} = {
            scope: 'sub',
            filter: '(sAMAccountName=' + username + ')',
            attributes: ['sAMAccountName'],
          };

          client.search(adSuffix, searchOptions, (err: any, res: any) => {
            assert.ifError(err);
            res.on('searchEntry', (entry: any) => {
              resp = true;

            });
            res.on('error', (error: any) => {
              console.log('err');
              reject(error.message);
            });

            await res.on('end', (result: any) => {
              resolve(resp);

            });
          });
        }
      });
    });
    return myPromise;

  }
于 2021-06-01T07:51:46.210 回答
0

使用 Bluebird Promises,最简单的方法是正常创建客户端,然后在客户端上运行 promisifyAll()。

var ldap = require('ldapjs');
var Promise = require('bluebird');

var client = ldap.createClient({
  url: 'ldap://my-server:1234',
});

Promise.promisifyAll(client);

现在您可以调用 client.addAsync() 和 client.searchAsync() 等。

client.bindAsync(secUserDn, secUserPassword)
  .then(doSearch) // if it works, call doSearch
  .catch(function (err) { // if bind fails, handle it
    console.error('Error on bind', err)
  });

function doSearch(data) {
  client.searchAsync('CN=A Test,OU=Users,DC=website,DC=com', options)
    .then(function (data) { // Handle the search result processing
      console.log('I got a result');
    })  
    .catch(function (err) { // Catch potential errors and handle them
      console.error('Error on search', err);
    });
}
于 2015-08-14T12:29:59.783 回答