Warden は Rack アプリケーションで認証を実装するときの定番です。だけど、ネットで見つかるのは OmniAuth と組み合わせるサンプルが比較的多め。
Warden を使ったサンプルで、自分にとってわりやすいものが見つからなかったので、試しに書いてみました。Sinatra と Warden のサンプルです。コードを単純にするため、ユーザー名とパスワードは test で固定しています。
# coding: utf-8 require "sinatra" require "warden" # Sinatra のセッションを有効にする enable :sessions # ユーザー ID をもとにユーザー情報を取得する # 今回は単なる Hash だけど、実際の開発ではデータベースから取得するはず Warden::Manager.serialize_from_session do |id| { :name => id, :password => "test" } end # ユーザー情報からセッションに格納する ID を取り出す Warden::Manager.serialize_into_session do |user| user[:name] end # ユーザー名 test、パスワード test のときだけログイン成功にする # 認証方式を登録。 # 実際に開発するときは、データベースに保存しているユーザー情報と # 照合するなり、OAuth 使うなりするはず。 Warden::Strategies.add :login_test do # 認証に必要なデータが送信されているか検証 def valid? params["name"] || params["password"] end # 認証 def authenticate! if params["name"] == "test" && params["password"] == "test" # ユーザー名とパスワードが正しければログイン成功 user = { :name => params["name"], :password => params["password"] } success!(user) else # ユーザー名とパスワードのどちらかでも間違っていたら # ログイン失敗 fail!("Could not log in") end end end # Warden の設定 use Warden::Manager do |manager| # 先ほど登録したカスタム認証方式をデフォルトにする manager.default_strategies :login_test # 認証に失敗したとき呼び出す Rack アプリを設定(必須) manager.failure_app = Sinatra::Application end # ログインしていないときは、ログインフォームを表示。 # ログインしているときは、ログイン済ページを表示。 get "/" do if request.env["warden"].user.nil? erb :login else erb :success_login end end # 認証を実行する。 # 成功すればトップページに移動。 post "/login" do request.env["warden"].authenticate! redirect "/" end # 認証に失敗したとき呼ばれるルート。 # ログイン失敗ページを表示してみる。 post "/unauthenticated" do erb :fail_login end # ログアウトする。 # ログアウト後はトップページに移動。 get "/logout" do request.env["warden"].logout redirect "/" end __END__ @@layout <!DOCTYPE html> <html> <head> <title>Sinatra-Warde</title> </head> <body> <%= yield %> </body> </html> @@success_login <h1>Hello Sinatra-Warden</h1> <a href="/logout">Logout</a> @@login <h1>Login</h1> <form method="POST" action="/login"> <fieldset> <label for="name">Name</label> <input type="text" name="name" /> </fieldset> <fieldset> <label for="password">Password</label> <input type="password" name="password" /> </fieldset> <input type="submit" value="Login" /> </form> @@fail_login <h1>Fail Login</h1> <a href="/">Retry Login</a>