2012-02-11
OmniAuth と Warden を WardenOmniAuth で連携してみた
Twitter の OAuth を使って認証するのに OmniAuth を使ってみたけど、Warden と組み合わせるのが定番みたいです。
Warden と組み合わせると、ログイン成功後のユーザー情報をセッションにつめたり、ログアウトしたり、といった処理を Warden に任せられます。まぁ、ユーザー情報をデータベースに保存する場合は、その部分を書かないといけませんけどね。
Sinatra + Warden + OmniAuth + WardenOmniAuth のサンプルは次の通り。データベースは使っていません。
# coding: utf-8 require "sinatra" require "warden" require "omniauth" require "omniauth-twitter" require "warden_omniauth" # Sinatra の有効にする enable :sessions # Warden の設定 Warden::Manager.serialize_into_session do |user| # user はハッシュなので、そのままセッションに入れる user end Warden::Manager.serialize_from_session do |user| # セッションから取り出した user はハッシュなので、そのまま利用する user end use Warden::Manager do |config| # 認証に失敗したときも Sinatra::Application を呼び出す config.failure_app = Sinatra::Application # デフォルトでは OmniAuth の Twitter 認証を使う config.default_strategies :omni_twitter end # OmniAuth の設定 use OmniAuth::Builder do provider :twitter, "ConsumerKey", "ConsumerSecret" end # WardenOmniAuth の設定 use WardenOmniAuth do |config| config.redirect_after_callback = "/warden/callback" end helpers do def warden request.env["warden"] end def current_user warden.user end end get "/" do erb :index end get "/warden/callback" do erb :home end get "/logout" do request.env["warden"].logout redirect "/" end get "/auth/failure" do params[:message] end __END__ @@layout <!DOCTYPE html> <html> <head> <title>Warden-OmniAuth</title> </head> <body> <%= yield %> </body> </html> @@index <h1>ログイン</h1> <a href="/auth/twitter">Twitter でログイン</a> @@home <h1>Wellcome</h1> <pre> <%# ログインユーザーを出力する %> <%= current_user %> </pre>
たまにリダイレクトループになって失敗するときあります。というか、昨日まで動かなかったのに、今日やったら上手く動くようになってました。しかも今度は全然失敗しないし。おかげで失敗した原因が調べられない…。同じ現象に遭遇した人いませんか?
2012-02-10
Rails3 レシピブック
まだ Rails2 が主流だったころ Rails を勉強していたんですが、Google App Engine が出たので、途中でやめて Python に移ってしまいました。それから去年までずっと Python。
今年から Ruby に戻って、Rails3 に再挑戦しています。Python で Django や Kay といったフレームワーク使っていたから、Rails2 のときどこで躓いていたのかわからないくらい、Rails3 にすんなり入れました。他のフレームワークで培ったノウハウは Rails でも生かせる、というのを実感中。
足りないのは「Rails3 ではメールどうやればいいんだっけ」「Rails3 ではリレーションどうすればいいんだっけ」といった、Rails3 でのやり方くらいです。そこで本書のようなレシピブックの出番。
Google 先生に聞くのもいいですけど、やっぱり手元にあった方が調べるのに早いです。本書は Rails 入門レベルのレシピからだんだん高度になっていくので、Rails 入門したてでもなんとか読み進めていける内容だと思います。
Rails 初挑戦でいきなり本書だけ、っていうのはさすがにキツイと思いますが、既に他の言語でフレームワークに慣れ親しんでいる人なら、Rails の勉強はレシピブックとネットの情報で足りるんじゃないでしょうか。私の場合は、今のところ何とかなっています。
ソフトバンククリエイティブ
売り上げランキング: 60469
2012-02-08
Ruby でベンチマーク計測
Java のサーブレットコンテナ、まぁ Jetty なんですけど、Jetty の HTTP サーバーとしての性能がどれくらいか分かる資料が無かったので、Ruby でベンチマークを計測するスクリプトを書いてみました。ついでにサーブレットも計測しています。benchmark モジュール初挑戦。
# coding: utf-8 require "open-uri" require "benchmark" HTML_URL = "http://192.168.56.101:8080/helloworld/" SERVLET_URL = HTML_URL + "hello" # ベンチマーク対象のメソッド def open_service(uri) # 指定した URI にアクセスしてレスポンスを取得するだけ open uri do |s| s.read end end # 渡したブロックを 1, 10, 100, 1000 回繰り返すのにかかる時間を計測 def do_benchmark(caption, &block) Benchmark.benchmark(caption + Benchmark::CAPTION, 7, Benchmark::FMTSTR) do |r| [1, 10, 100, 1000].each do |n| # block を n 回繰り返したときのベンチマーク r.report n.to_s do n.times &block end end end end # 静的ファイルにアクセス do_benchmark("static ") do open_service(HTML_URL) end puts # サーブレットにアクセス do_benchmark("servlet") do open_service(SERVLET_URL) end
このスクリプトを実行した結果は次の通り。
C:\work>ruby benchmark_jetty.rb static user system total real 1 0.078000 0.312000 0.390000 ( 0.419042) 10 0.016000 0.000000 0.016000 ( 0.128013) 100 0.156000 0.078000 0.234000 ( 1.221122) 1000 0.764000 1.560000 2.324000 ( 12.743274) servlet user system total real 1 0.000000 0.000000 0.000000 ( 0.014002) 10 0.000000 0.016000 0.016000 ( 0.134013) 100 0.063000 0.156000 0.219000 ( 1.281129) 1000 1.451000 0.670000 2.121000 ( 13.073307)
このスクリプトで計測したデータが、実際に役に立つかどうかは微妙ですけどね。ていうか、たぶん JMeter あたりを使って計測し直すこと間違いなし。
2012-02-06
Sequel でマイグレーション
Sequel にはマイグレーション機能があるので、Rails と同じようにテーブルの作成やスキーマ変更ができます。
サンプル程度ならアプリケーションのファイルに create_table べた書きでいいけど、ちゃんとしたサービス作るときはマイグレーションを使ったほうが良いですよね。
マイグレーションファイルの名前は、最初に通し番号またはタイムスタンプを付けて、APP_ROOT/db/migrate ディレクトリに配置するのが慣習。
001_create_users.rb
Sequel.migration do up do create_table :users do primary_key :id String :name, :null => false String :password, :null => false DateTime :created_at end end down do drop_table :users end end
あとは APP_ROOT で次のコマンドを実行。
sequel -m ./db/migrate sqlite://sample.db
たったこれだけ。簡単ですね。sqlite://〜 の部分は、使っているデータベースに合わせて修正してください。
2012-02-03
Sinatra + OmniAuth で Twitter の OAuth を試してみた
Sinatra アプリの認証に Warden を使おうとしてたけど、「ユーザー名とパスワードを自前で保存したくない」と思い直して、OAuth や OpenID を検討し始めました。Twitter や Facebook や GitHub など、いろんな OAuth に対応したいから、使うライブラリは OmniAuth かな。
Sinatra + OmniAuth で、Twitter の OAuth を使って認証するサンプルを書いてみました。
# coding: utf-8 require "sinatra" require "omniauth" require "omniauth-twitter" # Twitter の OAuth を使うなら必須 # Sinatra のセッションを有効にする enable :sessions # OmniAuth の設定 use OmniAuth::Builder do # Twitter の OAuth を使う provider :twitter, "Consumer key", "Consumer secret" end get "/" do erb :index end # Twitter の認証が成功したら呼び出される get "/auth/:provider/callback" do # 認証情報は request.env に格納されている @auth = request.env["omniauth.auth"] erb :home end __END__ @@layout <!DOCTYPE html> <html> <head> <title>Sinatra-OmniAuth</title> </head> <body> <%= yield %> </body> </html> @@index <a href="/auth/twitter">Twitter でログイン</a> @@home <h1>Wellcome</h1> <pre> <%= @auth %> </pre>
たったこれだけのコードで実装できてしまった…。以前、Python + AppEngine + Kay Framework で Twitter の OAuth に挑戦したときは、結構コード書いたのにな。


