如何在nodejs控制台中隐藏密码?

我需要隐藏密码input的function。 我在stackoverflow中看到很多答案。 但有了它,我不能validation价值,如果我按退格键。 条件返回false。

其他答案在variables中添加字符缓冲区。

  • 如果我按下“A”,退格键“B”,我在我的variables里就是这样的:“\ u0041 \ u0008 \ u0042”而不是“B”。

我有 :

var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question("password : ", function(password) { console.log("Your password : " + password); }); 

这可以通过readline通过静音stream拦截输出来处理,就像在npm( https://github.com/isaacs/read/blob/master/lib/read.js )的读取项目中所做的那样:

 var readline = require('readline'); var Writable = require('stream').Writable; var mutableStdout = new Writable({ write: function(chunk, encoding, callback) { if (!this.muted) process.stdout.write(chunk, encoding); callback(); } }); mutableStdout.muted = false; var rl = readline.createInterface({ input: process.stdin, output: mutableStdout, terminal: true }); rl.question('Password: ', function(password) { console.log('\nPassword is ' + password); rl.close(); }); mutableStdout.muted = true; 

要隐藏您的密码input,您可以使用:

第一个解决scheme:“密码:[= – ]”

这个解决scheme在按下button时有animation:

 password : [-=] password : [=-] 

代码 :

 var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function hidden(query, callback) { var stdin = process.openStdin(), i = 0; process.stdin.on("data", function(char) { char = char + ""; switch (char) { case "\n": case "\r": case "\u0004": stdin.pause(); break; default: process.stdout.write("\033[2K\033[200D"+query+"["+((i%2==1)?"=-":"-=")+"]"); i++; break; } }); rl.question(query, function(value) { rl.history = rl.history.slice(1); callback(value); }); } hidden("password : ", function(password) { console.log("Your password : " + password); }); 

这个序列“\ 033 [2K \ 033D”使用两个转义序列:

  • Esc [2K:清除整行。
  • Esc D:移动/滚动窗口一行。

要了解更多信息,请阅读: http : //ascii-table.com/ansi-escape-sequences-vt-100.php

第二个解决scheme:“密码:****”

 var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function hidden(query, callback) { var stdin = process.openStdin(); process.stdin.on("data", function(char) { char = char + ""; switch (char) { case "\n": case "\r": case "\u0004": stdin.pause(); break; default: process.stdout.write("\033[2K\033[200D" + query + Array(rl.line.length+1).join("*")); break; } }); rl.question(query, function(value) { rl.history = rl.history.slice(1); callback(value); }); } hidden("password : ", function(password) { console.log("Your password : " + password); }); 

您可以使用readline-sync模块而不是节点的readline

密码隐藏function是通过它的“hideEchoBack”选项内置的。

https://www.npmjs.com/package/readline-sync

想要添加到标记的解决scheme#2。

当我们检测到行结束,我相信我们应该删除事件处理程序,而不是只是stdin.pause() 。 这可能是一个问题,如果你在等待rl.question / rl.prompt其他地方。 在这些情况下,如果使用了stdin.pause() ,那么只会退出程序而不会给出任何错误,并且可能会非常烦人的进行debugging。

 function hidden(query, callback) { var stdin = process.openStdin(); var onDataHandler = function(char) { char = char + ""; switch (char) { case "\n": case "\r": case "\u0004": // Remove this handler stdin.removeListener("data",onDataHandler); break;//stdin.pause(); break; default: process.stdout.write("\033[2K\033[200D" + query + Array(rl.line.length+1).join("*")); break; } } process.stdin.on("data", onDataHandler); rl.question(query, function(value) { rl.history = rl.history.slice(1); callback(value); }); } 

也可以使用tty.ReadStream
process.stdin改变模式
禁用回显input字符。

 let read_Line_Str = ""; let credentials_Obj = {}; process.stdin.setEncoding('utf8'); process.stdin.setRawMode( true ); process.stdout.write( "Enter password:" ); process.stdin.on( 'readable', () => { const chunk = process.stdin.read(); if ( chunk !== null ) { read_Line_Str += chunk; if( chunk == "\n" || chunk == "\r" || chunk == "\u0004" ){ process.stdout.write( "\n" ); process.stdin.setRawMode( false ); process.stdin.emit('end'); /// <- this invokes on.end }else{ // providing visual feedback process.stdout.write( "*" ); } }else{ //console.log( "readable data chunk is null|empty" ); } } ); process.stdin.on( 'end', () => { credentials_Obj.user = process.env.USER; credentials_Obj.host = 'localhost'; credentials_Obj.database = process.env.USER; credentials_Obj.password = read_Line_Str.trim(); credentials_Obj.port = 5432; // connect_To_DB( credentials_Obj ); } );