提问人:Alfred 提问时间:1/17/2011 更新时间:4/16/2022 访问量:23352
使用 node.js 从输入中获取密码
Get password from input using node.js
答:
5赞
Alfred
1/17/2011
#1
为此,我找到了这篇出色的 Google Group 帖子
其中包含以下代码片段:
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
}
})
评论
0赞
mikemaccana
4/28/2012
注意 process.binding(“stdio”) 在当前版本的 node 中不再有效
16赞
mikemaccana
4/28/2012
#2
2015 年 12 月 13 日更新:readline
已替换,node_stdio已从节点 0.5.10 中删除。process.stdin
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]) } );
评论
0赞
user2226755
6/4/2014
无法验证值。如果您按退格键或其他非字母数字的触摸。
0赞
Scruffy
9/27/2015
require('tty').setRawMode()
已弃用。
4赞
Trent Mick
11/24/2012
#3
这是我从上面调整的 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;
}
});
}
评论
0赞
6/26/2015
您可以使用 的额外大小写语句来处理退格键。如果到目前为止的密码不为空,则可以用于将光标向后移动一列;之后,您可以写一个空格,然后再次向后移动。"u007F"
process.stdout.write('\033[<1>D')
0赞
coolaj86
12/13/2015
我更新了它以使用退格键,并将其与原始接受的答案合并,并添加了一个指向我计划继续改进的存储库的链接。
63赞
isaacs
11/24/2012
#4
为此,您可以使用阅读
模块(披露:由我编写):
在 shell 中:
npm install read
然后在你的 JS 中:
var read = require('read')
read({ prompt: 'Password: ', silent: true }, function(er, password) {
console.log('Your password is: %s', password)
})
更新现代版本(使用):await
const password = await read({
prompt: "Password: ",
silent: true,
replace: "*" //optional, will print out an asterisk for every typed character
};
console.log("Your password: " + password);
评论
2赞
paulolc
2/19/2013
github.com/isaacs/read - 在谷歌上搜索这个模块时遇到了一些麻烦,所以,为了方便起见,我在这里删除了一个指向它的链接。
2赞
mpen
9/11/2013
有同步版本吗?
1赞
josh3736
10/24/2013
@Mark:怎么会有?stdin 是一个流,用于触发事件。如果函数正在等待返回,则无法处理事件。
7赞
mpen
10/24/2013
@josh3736:我不知道,也许以同样的方式工作??readFileSync
0赞
bryanmac
12/10/2014
@josh3736:不是同步,但我使用模块 async.forEachSeries 或 async.forever 通过异步函数提出连续的输入问题。
1赞
Ciro Santilli OurBigBook.com
4/14/2022
今天避免回调@mpen的最佳解决方法是使用 / 顺便说一句:stackoverflow.com/a/71868483/895245async
await
2赞
Ciro Santilli OurBigBook.com
4/14/2022
#5
如何在不回调的情况下使用 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 如何防止 EAGAIN 错误,如果您稍后尝试使用 fs.readFileSync(0)
再次使用 stdin?
和 https://stackoverflow.com/a/10357818/895245 都会导致将来尝试从 stdin 读取 with 与 EAGAIN 中断。不知道如何解决这个问题。繁殖:read
fs.readFileSync(0)
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
评论