泣きながらDigest認証を行うnode.jsサーバを構築していて詰まったところがあったのでメモ。
passport.jsのdigest認証は、request時に受け付けたユーザIDを引数にして関数を組み、 DBなりと照合して最後のコールバックでパスワードをDigest Strategyコンストラクターに返す必要があるんだけれども、 コールバックで受け付けるパスワードがみた感じ平文でしか受け付けない。
javascript1passport.use(new DigestStrategy({ qop: 'auth' }, 2 function(username, done) { 3 User.findOne({ username: username }, function (err, user) { 4 if (err) { return done(err); } 5 if (!user) { return done(null, false); } 6 return done(null, user, user.password); //Wow, we must use plaintext... 7 }); 8 }, 9 function(params, done) { 10 // validate nonces as necessary 11 done(null, true) 12 } 13)); 14
は?これくそすぎないっすか・・・
ソースコード書き換えるしかないかと思って元のコード読んでたら、こんな事が書いてあった。
javascript1this._secret(creds.username, function(err, user, password) { 2 if (err) { return self.error(err); } 3 if (!user) { return self.fail(self._challenge()); } 4 5 var ha1; 6 if (!creds.algorithm || creds.algorithm === 'MD5') { 7 if (typeof password === 'object' && password.ha1) { 8 ha1 = password.ha1; 9 } else { 10 ha1 = md5(creds.username + ":" + creds.realm + ":" + password); 11 } 12 }else 13
137行目の部分、コールバックで返す際に ha1 というデータを持つObjectを返すと、 すでに{ユーザ名}:{realm}:{パスワード} をMD5ハッシュ化したものとして扱ってくれるみたいだ。 逆に単純なString形式の値を渡された場合、そのStringを使ってha1を作り出している。
(Digest認証で生成するハッシュのうちの一つですね)
料理できていればそのまま出すし、材料だけ渡されたら足りない部分を使って料理する感じ。 exampleにも書いておいて欲しかった・・・
ということで、 あらかじめデータベースには 上記のようなMD5ハッシュ値を保管しておき、Digest認証時に
javascript1 let md5HashedString = "a867af741df2e7004b62c10f38063db8"; //hash of "hoge:Users:hoge"; foo.ha1 = md5HashedString; return done(null, userId, foo.ha1); //callback to digestStrategy constructor. 2
で返してあげれば良さそうだ。
/以上
よかったらシェアしてください!