久々にmod_mrubyの話題のような気がします。
先日、 @hiroki_nazy さんからApacheの認証系の機能実装のpull-requestを頂いたの早速マージしておきました。機能詳細は、BlogかWikiに書いてくれるということなので、今回はざっとBasic認証のサンプルの紹介と、先ほど実装したRedis連携の機能追加を紹介します。
mod_mrubyでBasic認証
今回、 @hiroki_nazy さんが実装してくれた機能はApacheのBasic認証とDigest認証をmod_mruby上で実現するための機能です。
サンプルは以下のようになります。
まず、Apacheのconfに以下のような設定を記述します。
AuthType basic
AuthName "Message for clients"
AuthBasicProvider mruby
mrubyAuthnCheckPassword /var/www/html/auth.rb
require valid-user
</Location>
さらに、/var/www/html/auth.rbに以下のように記述します。
"bilbo" => "foo",
"frodo" => "bar",
"samwise" => "baz",
"aragorn" => "qux",
"legolas" => "quux",
"gimli" => "corge",
}
anp = Apache::AuthnProvider.new
if user_list[anp.user] == anp.password
Apache.return(Apache::AuthnProvider::AUTH_GRANTED)
else
Apache.return(Apache::AuthnProvider::AUTH_DENIED)
end
これによって、http://example.com/basic/ にアクセスがあると認証が求められ後、入力するとmrubyスクリプトがフックされ、上記のスクリプト内のanp.userとanp.passwordに入力したBasic認証の値が入って、評価されます。
Basic認証に、もう少し認証の条件を増やしたい場合等に有用なこと間違いなしでしょう。
mod_mrubyからRedis連携
mod_mrubyからRedis連携できるようにしました。
まずは、最低限の機能として、getとsetメソッドを実装しました。サンプルは以下のようになります。
r.content_type = "text/html"
a = Apache
host = "127.0.0.1"
port = 6379
a.rputs("> redis connect " + host + ":" + port.to_s + "<br>")
redis = Apache::Redis.new(host, port)
key = "hoge"
val = "aaaaaaaaaaaaaa"
a.rputs("> redis set " + key + " " + val + "<br>")
redis.set(key, val)
a.rputs("> redis get " + key + "<br>")
a.rputs(key + ": " + redis.get(key) + "<br><br>")
key = "hoge"
val = "bbbbbbbbbbbbbb"
a.rputs("> redis set " + key + " " + val + "<br>")
redis.set(key, val)
a.rputs("> redis get " + key + "<br>")
a.rputs(key + ": " + redis.get(key))
そして、Apacheにアクセスすると以下のように表示されます。
> redis set hoge aaaaaaaaaaaaaa
> redis get hoge
hoge: aaaaaaaaaaaaaa
> redis set hoge bbbbbbbbbbbbbb
> redis get hoge
hoge: bbbbbbbbbbbbbb
redis.set(key, value)でkeyとvalueをsetし、redis.get(key)でvalueをgetします。
今後は、柔軟にRedisと連携できるようにメソッドを追加していこうと考えています。使いどころとしては、mod_mrubyでproxyやvhost系の実装の際に、Redis経由で値をとってくるようにすると便利だと思います。イメージとしては、「lua-nginx-module の紹介 ならびに Nginx+Lua+Redisによる動的なリバースプロキシの実装案」を参考にすると良いと思います。
redis経由で認証する
では早速、上記の認証とredisを連携してみましょう。これらの機能によって、例えば以下のような実装が可能になります。
port = 6379
anp = Apache::AuthnProvider.new
redis = Apache::Redis.new(host, port)
if redis.get(anp.user) == anp.password
Apache.return(Apache::AuthnProvider::AUTH_GRANTED)
else
Apache.return(Apache::AuthnProvider::AUTH_DENIED)
end
redis-cliへ事前に以下のように、ユーザとパスワードを登録しておきます。
redis 127.0.0.1:6379> set matsumoto_r password1
OK
redis 127.0.0.1:6379> set matsumotory password2
OK
redis 127.0.0.1:6379> quit
$ redis-cli
redis 127.0.0.1:6379> get matsumoto_r
"password1"
redis 127.0.0.1:6379> quit
すると、Basic認証時のユーザとパスワードの組み合わせをRedisのKVSから抜き出すことができます。いい感じです。
さいごに
このように、Redisと認証を実装したことで、よりApacheをコントロールする事が楽しくなってきたと思います。プロキシ機能やrewrite機能、またはvhostの振り分けにRedis連携を使うとかなり便利になるだろうと考えています。今後は、mod_mrubyの機能をベースに、ngx_mrubyもできるだけ同等の機能を実装していきたいと思っています。
また、pull-requestはいちでもお待ちしていますので、Apacheの基本機能として今後これはいるだろうという機能があれば、mod_mrubyレポジトリまでいつでもpull-request下さい。
1 Comments.