【问题标题】:Use ldapjs with promise使用带有承诺的 ldapjs
【发布时间】:2015-06-06 12:01:51
【问题描述】:

我想将以下代码转换为使用 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);
        });
      });

    });

【问题讨论】:

    标签: javascript node.js promise ldapjs


    【解决方案1】:

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

    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。

    祝你编码好运)

    【讨论】:

      【解决方案2】:

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

      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);
      });
      

      【讨论】:

      • 我使用了您提供的代码。我收到错误:UNABLE_TO_VERIFY_LEAF_SIGNATURE,即使我有 process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';在我脚本的最顶端。
      • 这似乎不是承诺的问题,是吗?
      • 我不确定。如果我将它切换回我的原始代码,它正在使用 process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';如果将代码更改为:“return Promise.denodeify(search.on).call(search, 'searchEntry');”返回“某物”;异常停止。
      【解决方案3】:

      使用 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);
          });
      }
      

      【讨论】:

      • 答案和here一样吗?如果您认为问题重复,请投票关闭而不是复制答案。
      • 它们非常接近,但它们都出现在类似问题的搜索结果顶部。反正我没有那个能力。我认为您需要 3k 代表才能进行关闭/重新打开投票。
      【解决方案4】:

      我在这里遇到了同样的问题,但我通过添加 promiseresolve 响应而不使用 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;
      
        }
      

      【讨论】:

        猜你喜欢
        • 2015-08-28
        • 2018-03-09
        • 2011-09-24
        • 2016-04-02
        • 2020-07-20
        • 2018-11-18
        • 1970-01-01
        • 1970-01-01
        • 2013-06-17
        相关资源
        最近更新 更多