Ruby on Rails2.1でログイン画面の作成

Railsの勉強3日目です。そういえば、ログイン機能を作るのを忘れていました。今まではモデルの作成とCRUD画面およびそのためのコントローラーの作成は文字通りレールに乗っかって出来たわけですがログイン機能ってどうやって作るんだろう。。
私気づいたんですがレールから外れたことをやろうとすると急に難しくね?
どこから手をつけたらいいのかイマイチ分からずGoogleで色々と調べたところ、ログイン機能もほぼ自動で作成することができるっぽいです。参考にしたのは以下のサイトです。ありがとうございます!!
http://d.hatena.ne.jp/idesaku/20080430/1209579996
http://d.hatena.ne.jp/kugini/20080410/p1
http://blog.japan.zdnet.com/yoshimi/a/2008/03/restful_authent.html

準備

Railsの機能としては提供されて無いようで、ログイン機能を作るためのプラグインを入れる必要があるとのこと。なお、バージョン2系からは「restful_authentication」を使うみたいです。おぉRESTfulですか。正直よく分かってないんですよね。。まぁ分かってなくてもレールに乗っかって走れるところまでは走ってみよう。
それではまずプラグインのインストールです。

script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/

次に認証関連のモジュールを生成。生成時のコマンドにオプションを付与することもできるみたいなんですけどね、例えば一旦メールで仮認証状態にして再度アクセスした時に承認される、みたいなやつです。こんなんも自動で出来るのか!って感じですが今回はそこまでいらないので一番シンプルなヤツで。

script/generate authenticated user sessions

あらら、user作るのね。。memberモデル作ったのにな。けどレールから外れることはなるべくやめておこう。memberは削除して今後はこのuserでいくことにするか。ま、それは後からやるとして、とりあえず生成の後のお決まり処理実行。

rake db:migrate

実行

まずはユーザーの登録から。ttp://localhost:3000/users/newにアクセスするとこんな画面が表示されます。

で、登録すると、ttp://localhost:3000/に遷移します。今は何も変えていないのでデフォルトの画面が表示される。


次にログインをします。ttp://localhost:3000/session/newにアクセスするとこんな画面が表示されます。

失敗すると再度ログイン画面に遷移し、成功するとまたもやttp://localhost:3000/に遷移します。
URLとか遷移先は少しおかしいですがログインに関してもノンプログラミングでいけました。すごいな!

仕上げ

ttp://localhost:3000/にアクセスした際に、ログインが行われていたらプロジェクト一覧を表示し、ログインがまだならログイン画面を表示するように変更したい。

まずはデフォルトページを削除する。

rm public/index.html

次にconfig/route.rbを修正。一番最後のendの前に次の行を追加する。これでhttp://localhost:3000/にアクセスした時にProjectsControllerに遷移するようになる。

  map.root :controller => "projects"
end

次にログインしていなければURLを直撃されてもログインページに遷移させる方法です。
そのためにはAuthenticatedSystemをincludeする必要があります。デフォルトではUserControllerとSessionsControllerに追記されていますが、すべてのControllerの親クラスに追加すべき。
まずはUserControllerおよびSessionsControllerのこの2行を削除し、ApplicationControllerに追加する。

class UsersController < ApplicationController
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem

親クラスのApplicationControllerはモジュールをincludeするだけではなく、事前にログインが必要だということを記述します。

class ApplicationController < ActionController::Base
  include AuthenticatedSystem

  before_filter :login_required

ただこれだと全コントローラでログインが必要になってしまいます。ユーザーの登録処理を行うUsersControllerとログイン処理を行うSessionsControllerは次のようにしてログインが必要ないことを記述します。

class SessionsController < ApplicationController
  skip_before_filter :login_required

これでOKです。
今のところプログラムらしいプログラムしてないけど、ここまで出来た♪