Java の Console クラスの readPassword メソッドを用いたパスワードの入力
コンソールとは?
あとで Java のコードを紹介しますが、そこでコンソールという言葉が出てきますので、先にコンソールという言葉の意味を説明しておきます。
本来の意味では、コンピュータに命令を入力する物理的な装置のことを「ターミナル」(端末) といいます。 そして、ターミナルのうち文字・テキストによって命令を入力するテキスト端末のことを「コンソール」といいます。
ターミナルとして動作するソフトウェアのことを「ターミナル・エミュレータ」といいますが、慣例的には単に「ターミナル」とも言ったりします。
Windows に含まれるターミナル (エミュレータ) は「コマンドプロンプト」という名前のプログラムです。macOS ではその名の通り「ターミナル」という名前が付いています。
コンソールも同様で、ソフトウェアでその機能を実現するものを「仮想コンソール」とかあるいは単に「コンソール」といいます。
以上から結局、パソコン上のプログラム開発をしている時に単に「コンソール」といったら「コマンドプロンプト」(Windows) や「ターミナル」(mac) などの、 テキストベースのコマンド実行環境のことを指します。
パスワードの危ない入力方法
それでは実際に、ユーザーからの入力を受け取るプログラムを書いてみましょう。
Java でコンソールからの入力を受けとる簡単な方法として、Scanner クラスを利用する方法があります。
次のコードでは Scanner クラスの nextLine() でユーザーからの入力を受け取っています。
import java.util.Scanner;
public class PasswordTest1A {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter username: ");
String name = in.nextLine();
System.out.print("Enter password: ");
String password = in.nextLine();
showResult(name, password);
}
public static void showResult(String name, String password) {
System.out.println("==========");
System.out.println("Username: " + name);
System.out.println("Password: " + password);
}
}
入力を受け取ったら、その内容をそのまま表示しています。
このプログラムを実行すると、次のようになります。
これを見てわかるように、パスワードとして入力したい文字も、画面にタイプした内容がそのままエコーされて表示されてしまっています。 パスワードの入力形式としては大変危険です。
Console クラスの readPassword() メソッドでパスワードを安全に入力
そこで、次のようにパスワードの入力内容が画面に表示されないように修正しましょう。
これは macOS の Terminal での実行結果ですが、ここでは鍵アイコンが表示されて、入力内容が伏せられていることがわかります。
こうした動作はどのように実装すればよいでしょうか。
上では Scanner クラスの nextLine() メソッドを使って、 コンソールでの入寮内容を受け取りましたが、この方法を変更して、Console クラスを利用します。
Console クラスはパスワードを読み取ることを想定した readPassword() メソッドを持っています。これを使うと、 タイプした内容をローカルエコーしません。
import java.io.Console;
public class PasswordTest1B {
public static void main(String[] args) {
Console cons = System.console();
if (cons == null) {
System.out.println("con == null");
return;
}
String name = cons.readLine("Enter username: ");
char[] inChars = cons.readPassword("Enter password: ");
String password = new String(inChars);
showResult(name, password);
}
public static void showResult(String name, String password) {
System.out.println("==========");
System.out.println("Username: " + name);
System.out.println("Password: " + password);
}
}
Console クラスの readLine メソッドと readPassword メソッドを利用してコンソールへの入力を受け取っています。 どちらのメソッドも入力を促すプロンプトの文字列を受け取り、それを表示することができます。
現在のセッションでの Console オブジェクトは System.console() の戻り値として取得します。
Console が null の場合
このプログラムを Eclipse や IntelliJ などの統合開発環境で実行すると、System.console() で Console オブジェクトが取得できない場合があります。これは現在のセッションがコンソールに関連付けされていないためです。
その場合は、例えば IntelliJ なら IDE 内部でも Terminal を開く機能がありますので、そこで実行します。
あるいはターミナルを開いて、IDE の外でプログラムを実行すれば Console オブジェクトが取得できるはずです。