Padrinoで楽に認証の仕組み作りたい...
Padrino製のアプリに、Padrino-adminを使って
ユーザ認証作ればチョー楽できるよなーとか思ってたら、
padrino-wardenを見つけたので使ってみた。
OmniAuthじゃないものもあるのかと思ったので使ってみる。
それぞれの要素
Padrino
言わずもがな...
sinatraベースの自分が好んでいるWeb Application Framework。
Warden
wardenは、
Rack Middlewareを利用しているWAFで使える認証ライブラリ。
Padrino-warden
padrino-wardenは、WardenをPadrinoで利用できるように
Helperを追加がされており、楽に使える。
Padrino-admin
Padrinoプロダクトに包含されている
admin画面を作るもの。
scaffoldにて、padrino g admin
と、
padrino projectに対してscaffoldを実行すればadmin画面を作成できる。
こんなの。
padrino-adminの環境を構築するまで
padrinoを入れる
まあ、グローバルインストールすると楽。
> gem install padrino -V
generatorでサクッと作る
> padrino g project test-padrino-warden -t rspec -e haml -m mocha -s jquery -d activerecord -c sass
> cd test-padrino-warden
> bundle ins --path vendor/bundle
adminアプリを作成
Padrino-adminは、別アプリとして
Padrino側でPadrino-adminをマウントする。
まあ、scaffoldを使えば良い。
> cd test-padrino-warden
> padrino admin
DB migrate
DBのマイグレーションをする。
> bundle
> bundle ex db:create
> bundle ex db:marge
Adminのユーザを作る
以下のRake taskで作成できる。
> bundle ex db:seed
padrino-adminの確認
アプリを立ち上げて、padrino-adminへのアクセスを確認する。
> bundle ex rackup
> open http://localhost:9292/admin/sessions/new
OK。
wardenとpadrino-adminのつなぎ込み
wardenなどをインストール
Gemfileに、おもむろにpadrino-wardenをインストールするよう
追記しとく。
rubygemsで手に入るpadrino-wardenはバージョンが古い(0.1.0)。
githubからmaster branchを手に入れるようにする。
gem 'padrino', '0.12.2'
gem 'padrino-warden', :github => 'jondot/padrino-warden'
> bundle
app.rbにwarden provideの対応を行う
generatorが作成したapp.rbと
追記した結果のdiffを示す。
--- app.rbx 2014-07-12 19:07:15.000000000 +0900
+++ app.rb 2014-07-13 09:58:03.000000000 +0900
@@ -4,9 +4,36 @@
use ActiveRecord::ConnectionAdapters::ConnectionManagement
register Padrino::Mailer
register Padrino::Helpers
+ register Padrino::Warden
+ register Padrino::Warden::Helper
enable :sessions
+ set :auth_failute_path, '/sessions/login'
+ set :auth_success_path, '/'
+
+ Warden::Strategies.add(:password) do
+ def valid?
+ params['email'] || params['password']
+ end
+
+ def authenticate!
+ account = Account.authenticate(
+ params['email'], params['password']
+ )
+ account.nil? ? fail!('Invalid username of password') : success!(account)
+ end
+ end
+
+ Warden::Manager.serialize_into_session { |account| account.email }
+ Warden::Manager.serialize_from_session { |email| Account.where(email: email) }
+
+ before do
+ unless request.path == '/sessions/login'
+ return redirect '/sessions/login' unless authenticated?
+ end
+ end
+
##
# Caching support.
#
layouts/application templateを作る
${root}/app/views/layouts/application.haml
を作る。
%html
%head
%meta{:charset => "utf-8"}
= stylesheet_link_tag '//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'
= javascript_include_tag '//code.jquery.com/jquery-2.1.1.min.js'
= javascript_include_tag '//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js'
%title
Test - Padrino Warden -
%body
.navbar.navbar-default{ role: 'navigation' }
.container-fluid
.navbar-header
%a{ class: 'navbar-brand'}
Test - Padrino Warden -
.collapse.navbar-collapse
%ul.nav.navbar-nav.navbar-right
%li
%a{ href: "#" }
- if authenticated?
= "#{current_user.first.name} としてログイン"
- else
ログインしてません...
- if authenticated?
%li
%a{ href: "/sessions/logout" }
ログアウトする
= yield
sessions/login templateを作る
${root}/app/views/sessions/login.haml
を作る。
.container
%h1
login
= form_tag('/sessions/login', id: 'sessions_login', method: 'post', role: 'form', role: 'form') do
.form-group
%label.label(for='email') Login
= text_field_tag :email, type: 'email', class: 'form-control', value: params[:email]
.form-group
%label.label(for='password') Password
= password_field_tag :password, class: 'form-control'
= submit_tag('Sign in', class: 'btn btn-default')
Top pageを作る
index controllerを作る。名前はアレだが...
> padrino g controller index
index controllerを整える
TestPadrinoWarden::App.controllers :index do
get :index do
render :index
end
end
index/index.haml を作る
.container
%h1
Welcome to underground...
ログインの実験
Padrinoのアプリケーションを立ち上げ、テストしてみる。
アプリケーションの立ち上げ
Rackupで立ち上げ。
> bundle ex rackup
ブラウザでアプリにアクセスする。
> open http://localhost:9292/
ログインページが開いた。
メールアドレスとパスワードを入力して、
Sign inボタンを押すと、indexページが開く。
使ってみて
padrino-admin、気楽にアカウントを追加できるし、
roleの追加も行える。連携できるのは楽だ。
Wardenの組み込みはpadrino-wardenで問題なく行える。
current_user.first.role
などでroleについても取得できるし、色々使えそう。
成果物
以下のリポジトリに追加しておいた。