Login Manager を利用する
拡張機能はしばしば外部サイトや Web アプリケーション等のパスワードを安全に格納する必要があります。安全に実行するため次の機能を利用できます。nsILoginManager
は機密事項なパスワード情報のための安全なストレージを用意し、nsILoginInfo
はログイン情報を格納する方法を提供します。
nsILoginManager
を取得する
nsILoginManger
を実装するコンポーネントを得るためには以下のコードを利用します。
var passwordManager = Components.classes["@mozilla.org/login-manager;1"] .getService(Components.interfaces.nsILoginManager);
ログインマネージャの多くの関数は nsILoginInfo
オブジェクトを引数として利用します。nsILoginInfo
オブジェクトは次の属性を保有します。ホスト名、フォームのサブミット先 URL、HTTP realm、ユーザ名、ユーザ名フィールド、パスワード、パスワードフィールド。ホスト名、ユーザ名、パスワード属性は必須で、他のフィールドはログインが Web のページフォーム向けであるか、または HTTP/FTP 認証サイトのログインであるかにより設定されます。より詳細には nsILoginInfo
属性定義をご覧ください。nsILoginInfo
オブジェクトを定義するのは簡単です。
var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Components.interfaces.nsILoginInfo, "init"); var loginInfo = new nsLoginInfo(hostname, formSubmitURL, httprealm, username, password, usernameField, passwordField);
使用例
Web ページ向けログインを作成する
var formLoginInfo = new nsLoginInfo('https://www.example.com',
'https://login.example.com', null,
'joe', 'SeCrEt123', 'uname', 'pword');
このログインは以下のような HTML フォームに対応します。
<form action="https://login.example.com/foo/authenticate.cgi">
Please log in.
Username: <input type="text" name="uname">
Password: <input type="password" name="pword">
</form>
サイトの個人認証向けログインを作成する
var authLoginInfo = new nsLoginInfo('https://www.example.com',
null, 'ExampleCo Login',
'alice', 'SeCrEt321', "", "");
これはサーバ https://www.example.com が次のようなリプライを送ってきた場合のログインに対応します。
HTTP/1.0 401 Authorization Required Server: Apache/1.3.27 WWW-Authenticate: Basic realm="ExampleCo Login"
ローカル上の拡張機能向けログインを作成する
var extLoginInfo = new nsLoginInfo('chrome://firefoo',
'User Registration', null,
'bob', '123sEcReT', "", "");
ログインマネージャはこれを Web サイトログインであるかのように扱います。開発者は他の拡張機能と衝突することを防ぐため自分の拡張機能の chrome:// の URL とログインの目的を簡潔に示す realm 文字列を使用しなければなりません。
パスワードを格納する
ログインマネージャにパスワードを格納するために、最初に nsILoginInfo
オブジェクトを上記で定義したように作成する必要があります。次に単純に nsILoginManager
のメソッド、addLogin()
をコールしてください。
myLoginManager.addLogin(loginInfo);
NULL
の場合に例外を投げます。パスワードを格納するときには一つは指定されなければなりません。 <tt>hostname</tt>、<tt>username</tt>、<tt>password</tt> も必須引数です。
パスワードを取得する
ログインマネージャからパスワードを取得するのはもう少し難しくなります。パスワードを導くための <tt>hostname</tt>、<tt>formSubmitURL</tt>、<tt>httprealm</tt> はパスワードを見つけるために格納された情報と完全一致しなければなりません。ただ一つの例外はもし <tt>formSubmitURL</tt> が空文字列で格納された場合、<tt>formSubmitURL</tt> 引数は無視されます。<tt>hostname</tt> と <tt>formSubmitURL</tt> の引数が完全な URL からパスを含まないように注意してください。次の例をフォームログインのスターティングポイントとしてご利用ください。
var hostname = 'https://www.example.com'; var formSubmitURL = 'https://www.example.com'; // https://www.example.com/foo/auth.cgi ではない var httprealm = null; var username = 'user'; var password; try { // ログインマネージャを得る var myLoginManager = Components.classes["@mozilla.org/login-manager;1"] .getService(Components.interfaces.nsILoginManager); // 与えられた引数に対応する複数のユーザを見つける var logins = myLoginManager.findLogins({}, hostname, formSubmitURL, httprealm); // 返り値の nsILoginInfo オブジェクトの配列から該当するユーザを見つける for (var i = 0; i < logins.length; i++) { if (logins[i].username == username) { password = logins[i].password; break; } } } catch(ex) { // nsILoginManger コンポーネントが存在しない場合のみ発生する }
ユーザが複数のパスワードを保護するためにマスターパスワード設定している場合、ユーザはマスターパスワードの入力を求められます。
パスワードを削除する
パスワードの削除は簡単です。
myLoginManager.removeLogin(loginInfo);
パスワードを削除するときに、指定された nsILoginInfo
オブジェクトは格納された値と完全に一致しなければなりません。そうでなければ例外が発生します。これはパスワード属性を含みます。次の例はパスワードが何であるか実際には知らない場合にパスワードを削除する方法です。
// 例としての値 var hostname = 'https://www.example.com'; var formSubmitURL = 'https://www.example.com'; var httprealm = null; var username = 'user'; try { // ログインマネージャを獲得する var passwordManager = Components.classes["@mozilla.org/login-manager;1"] .getService(Components.interfaces.nsILoginManager); var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Components.interfaces.nsILoginInfo); // この拡張機能のユーザを見つける var logins = passwordManager.findLogins({}, hostname, formSubmitURL, httprealm); for (var i = 0; i < logins.length; i++) { if (logins[i].username == username) { passwordManager.removeLogin(logins[i]); break; } } } catch(ex) { // これは nsILoginManger コンポーネントクラスが存在しない場合のみ発生する }
格納済みログイン情報を変更する
パスワードの変更はとても簡単です。removeLogin()
の呼び出しに続いて addLogin()
の呼び出しを行うだけだからです。両者に共通する警告として <tt>oldLogin</tt> は既存のログインと完全一致する必要があります(上記をご覧ください)。 <tt>newLogin</tt> 属性は正しく設定される必要があります。
myLoginManager.modifyLogin(oldLogin, newLogin);
デバッグ
ログインマネージャの実装にはエラーコンソールにデバッグメッセージを送る機能があり、ログインマネージャが何を行っているかを見ることができます。デバッグログを有効にする方法は https://wiki.mozilla.org/Firefox:Pass...ager_Debugging を参照して下さい。
古いバージョンの Firefox をサポートするために
拡張機能が Firefox 3 と以前のバージョンの両者をサポートさせたい場合に nsILoginManager
と nsIPasswordManager
の両方のコンポーネントを実装する必要があります。これを簡単に行う方法は以下のようになります。
if ("@mozilla.org/passwordmanager;1" in Components.classes) { // パスワードマネージャが存在する場合、Firefox 3 ではない (Firefox 2 や Netscape、SeaMonkey 等) // パスワードマネージャのコードを記述する } else if ("@mozilla.org/login-manager;1" in Components.classes) { // ログインマネージャが存在するので Firefox 3 である // ログインマネージャのコードを記述する }