使用node.js从输入中获取密码

发布于 2024-10-12 04:49:52 字数 48 浏览 2 评论 0原文

如何使用node.js从输入中获取密码?这意味着您不应该输出在控制台中输入的密码。

How to get password from input using node.js? Which means you should not output password entered in console.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谜兔 2024-10-19 04:49:52

您可以使用 read 模块(披露:书面由我) 为此:

在你的 shell 中:

npm install read

然后在你的 JS 中:

var { read } = require('read')
read({ prompt: 'Password: ', silent: true }, function(er, password) {
  console.log('Your password is: %s', password)
})

或者使用 ESM 和 await

import { read } from "read";

const password = await read({
  prompt: "Password: ",
  silent: true,
  replace: "*" //optional, will print out an asterisk for every typed character 
});
console.log("Your password: " + password);

You can use the read module (disclosure: written by me) for this:

In your shell:

npm install read

Then in your JS:

var { read } = require('read')
read({ prompt: 'Password: ', silent: true }, function(er, password) {
  console.log('Your password is: %s', password)
})

Or using ESM and await:

import { read } from "read";

const password = await read({
  prompt: "Password: ",
  silent: true,
  replace: "*" //optional, will print out an asterisk for every typed character 
});
console.log("Your password: " + password);
似狗非友 2024-10-19 04:49:52

更新2015 年 12 月 13 日readline已替换 process.stdinnode_stdio 已从 Node 0.5.10 中删除< /a>.

var BACKSPACE = String.fromCharCode(127);


// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}

getPassword('Password: ', (ok, password) => { console.log([ok, password]) } );

Update 2015 Dec 13: readline has replaced process.stdin and node_stdio was removed from Node 0.5.10.

var BACKSPACE = String.fromCharCode(127);


// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}

getPassword('Password: ', (ok, password) => { console.log([ok, password]) } );
-柠檬树下少年和吉他 2024-10-19 04:49:52

为此,我找到了这篇出色的 Google 网上论坛帖子

其中包含以下片段:

var stdin = process.openStdin()
  , stdio = process.binding("stdio")
stdio.setRawMode()

var password = ""
stdin.on("data", function (c) {
  c = c + ""
  switch (c) {
    case "\n": case "\r": case "\u0004":
      stdio.setRawMode(false)
      console.log("you entered: "+password)
      stdin.pause()
      break
    case "\u0003":
      process.exit()
      break
    default:
      password += c
      break
  }
})

To do this I found this excellent Google Group post

Which contains the following snippet:

var stdin = process.openStdin()
  , stdio = process.binding("stdio")
stdio.setRawMode()

var password = ""
stdin.on("data", function (c) {
  c = c + ""
  switch (c) {
    case "\n": case "\r": case "\u0004":
      stdio.setRawMode(false)
      console.log("you entered: "+password)
      stdin.pause()
      break
    case "\u0003":
      process.exit()
      break
    default:
      password += c
      break
  }
})
生生不灭 2024-10-19 04:49:52

这是我对上面的nailer进行了调整的版本,已更新以获取回调并用于节点0.8的使用:

/**
 * Get a password from stdin.
 *
 * Adapted from <http://stackoverflow.com/a/10357818/122384>.
 *
 * @param prompt {String} Optional prompt. Default 'Password: '.
 * @param callback {Function} `function (cancelled, password)` where
 *      `cancelled` is true if the user aborted (Ctrl+C).
 *
 * Limitations: Not sure if backspace is handled properly.
 */
function getPassword(prompt, callback) {
    if (callback === undefined) {
        callback = prompt;
        prompt = undefined;
    }
    if (prompt === undefined) {
        prompt = 'Password: ';
    }
    if (prompt) {
        process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch + "";

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}

Here is my tweaked version of nailer's from above, updated to get a callback and for node 0.8 usage:

/**
 * Get a password from stdin.
 *
 * Adapted from <http://stackoverflow.com/a/10357818/122384>.
 *
 * @param prompt {String} Optional prompt. Default 'Password: '.
 * @param callback {Function} `function (cancelled, password)` where
 *      `cancelled` is true if the user aborted (Ctrl+C).
 *
 * Limitations: Not sure if backspace is handled properly.
 */
function getPassword(prompt, callback) {
    if (callback === undefined) {
        callback = prompt;
        prompt = undefined;
    }
    if (prompt === undefined) {
        prompt = 'Password: ';
    }
    if (prompt) {
        process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch + "";

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}
场罚期间 2024-10-19 04:49:52

如何在没有回调的情况下使用read

通过async/await,我们可以通过遵循标准模式:

const readCb = require('read')

async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      if (err) {
        reject(err)
      } else {
        resolve(line)
      }
    })
  })
}

;(async () => {
  const password = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
})()

令人烦恼的是,您必须将 async/await 传播到整个调用堆栈,但这通常是正确的方法,因为它清楚地标记了什么是异步的或不是异步的。

在“read”上测试:“1.0.7”,Node.js v14.17.0。

TODO 如果稍后尝试通过 fs.readFileSync(0) 再次使用 stdin,如何防止 EAGAIN 错误?

readhttps://stackoverflow.com/a/10357818/895245 导致将来尝试使用 fs.readFileSync(0) 从标准输入读取 与 EAGAIN 决裂。不知道如何解决这个问题。复制:

const fs = require('fs')
const readCb = require('read')

async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      resolve([err, line])
    })
  })
}

;(async () => {
  const [err, password] = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()

或:

#!/usr/bin/env node

const fs = require('fs')

var BACKSPACE = String.fromCharCode(127);

// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}

async function read(opts) {
  return new Promise((resolve, reject) => {
    getPassword(opts, (err, line) => {
      resolve([err, line])
    })
  })
}

;(async () => {
  const [err, password] = await read('Password: ')
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()

错误:

fs.js:614
  handleErrorFromBinding(ctx);
  ^

Error: EAGAIN: resource temporarily unavailable, read
    at Object.readSync (fs.js:614:3)
    at tryReadSync (fs.js:383:20)
    at Object.readFileSync (fs.js:420:19)
    at /home/ciro/test/main.js:70:18
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  errno: -11,
  syscall: 'read',
  code: 'EAGAIN'
}

询问于:https://github.com/npm/read/issues /39

How to use read without a callback

With async/await, we can get rid of the annoying callback with the following standard pattern:

const readCb = require('read')

async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      if (err) {
        reject(err)
      } else {
        resolve(line)
      }
    })
  })
}

;(async () => {
  const password = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
})()

The annoyance is that then you have to propagate async/await to the entire call stack, but it is generally the way to go, as it clearly marks what is async or not.

Tested on "read": "1.0.7", Node.js v14.17.0.

TODO how to prevent EAGAIN error if you try to use stdin again later with fs.readFileSync(0)?

Both read and https://stackoverflow.com/a/10357818/895245 cause future attempts to read from stdin with fs.readFileSync(0) to break with EAGAIN. Not sure how to fix that. Reproduction:

const fs = require('fs')
const readCb = require('read')

async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      resolve([err, line])
    })
  })
}

;(async () => {
  const [err, password] = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()

or:

#!/usr/bin/env node

const fs = require('fs')

var BACKSPACE = String.fromCharCode(127);

// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }

    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');

    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');

        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}

async function read(opts) {
  return new Promise((resolve, reject) => {
    getPassword(opts, (err, line) => {
      resolve([err, line])
    })
  })
}

;(async () => {
  const [err, password] = await read('Password: ')
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()

Error:

fs.js:614
  handleErrorFromBinding(ctx);
  ^

Error: EAGAIN: resource temporarily unavailable, read
    at Object.readSync (fs.js:614:3)
    at tryReadSync (fs.js:383:20)
    at Object.readFileSync (fs.js:420:19)
    at /home/ciro/test/main.js:70:18
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  errno: -11,
  syscall: 'read',
  code: 'EAGAIN'
}

Asked at: https://github.com/npm/read/issues/39

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文