acts_as_authenticated を試してみた。
LoginEngine が使えなくて困ってたらacts_as_authenticatedがいいらしいってことで試してみたのでメモ。
> komagata さんありがとうございます!
とりあえず、サインアップする機能だけはでけた。
=> sendmail を使うように
config/environments/development.rb
app/models/user_notifier.rb 各メソッドの以下の値を設定
activation_code, activated_at というフィールドが必要。
migrate/003_alter_user.rb を作成
app/models/user.rb
app/controllers/account_controller.rb
app/views/user_notifier/signup_notification.rhtml
app/views/account/signup_notification.rhtml
app/views/account/activate.rhtml
1. なにはなくとも、acts_as_authenticated をインストール
$ ruby script/plugin discover $ ruby script/plugin install acts_as_authenticated■ model, controller などを生成
$ ./script/generate authenticated user account■ migrate を実行してテーブルを作成
$ rake db:migrateここまででとりあえず試してみる。 http://localhost:3000/account/signup にアクセスすると、サインアップ画面がでるので入力してみる。 Submit すると、なんか以下のようなぽえむが...
In the Caboose. "Train delayed? and what's to say?" "Blocked by last night's snow they say." Seven hours or so to wait; Well, that's pleasant! but there's the freight. Depot loafing no one fancies, We'll try the caboose and take our chances. : :■ 不安なのでDBを確認してみる。
mysql> select * from users \G
*************************** 1. row ***************************
id: 1
login: hoge
email: hoge@example.com
crypted_password: f3a1c761b346e00b5efaf3a52428cbbb531fda7b
salt: c997dd5f8793cfe6d4559fb430eb87738a41c4d0
created_at: 2007-07-05 00:41:32
updated_at: 2007-07-05 00:41:32
remember_token: NULL
remember_token_expires_at: NULL
1 row in set (0.00 sec)
入ってる。とりあえず、サインアップする機能だけはでけた。
2. メールのセットアプ
http://technoweenie.stikipad.com/plugins/show/Mailer+Setup$ ./script/generate authenticated_mailer user■ config/environment.rb を修正 (Rails 1.2 以上)
Rails::Initializer.run do |config| config.active_record.observers = :user_observer end■ メールが送れないよ (localhost に smtp接続できない)
=> sendmail を使うように
config/environments/development.rb
ActionMailer::Base.delivery_method = :sendmail■ メールのサブジェクト、送信者を設定
app/models/user_notifier.rb 各メソッドの以下の値を設定
@subject @body[:url] @fromYOURSITE の部分をどうすればいいのかわからん。
3. Activatioin機能
http://technoweenie.stikipad.com/plugins/show/User+Activation ■ DBスキーマ変更activation_code, activated_at というフィールドが必要。
migrate/003_alter_user.rb を作成
class AlterUsers < ActiveRecord::Migration
def self.up
add_column :users, :activation_code, :string, :limit => 40
add_column :users, :activated_at, :datetime
end
def self.down
remove_column :users, :activation_code
remove_column :users, :activated_at
end
end
(このmigrateのファイル名とクラス名に何か規約があるのかないのかよくわかってない)
migrate を実行
$ rake db:migrate■ User モデルの変更
app/models/user.rb
class User < ActiveRecord::Base
before_create :make_activation_code
# loginと非暗号のパスワードから認証し、userかnilを返す
def self.authenticate(login, password)
# activated_at が NULL以外
u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]
u && u.authenticated?(password) ? u : nil
end
# ユーザーを有効化する
def activate
@activated = true
update_attributes(:activated_at => Time.now.utc, :activation_code => nil)
end
# 有効化されてたら true 返す
def recently_activated?
@activated
end
protected
# 有効化コードを生成する
def make_activation_code
self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
end
end
■ accountコントローラを修正
app/controllers/account_controller.rb
class AccountController < ApplicationController
:
def signup
@user = User.new(params[:user])
return unless request.post?
@user.save!
# self.current_user = @user # activate するまえにログインしちゃいや
# redirect_back_or_default(:controller => '/account', :action => 'index')
redirect_to(:action => 'signup_notification')
flash[:notice] = "Thanks for signing up!"
rescue ActiveRecord::RecordInvalid
render :action => 'signup'
end
def signup_notification
end
# 有効化
def activate
@user = User.find_by_activation_code(params[:id])
if @user and @user.activate
self.current_user = @user
# redirect_back_or_default(:controller => '/account', :action => 'index')
flash[:notice] = "Your account has been activated."
end
end
end
■ メールの本文のテンプレートを変更app/views/user_notifier/signup_notification.rhtml
アカウントが作成されました。 ユーザー名: <%= @user.login %> パスワード: <%= @user.password %> アカウントを有効化する為に以下のURLにアクセスしてください。 <%= @url %>app/views/user_notifier/activation.rhtml
<%= @user.login %>さん ユーザー登録が完了しました。 <%= @url %>UTF8で日本語思いっきりかいたけど文字化けしないで届いたぞ! ISO-2022-JPじゃないとあとで、いろいろ困りそうな気がする(携帯とか)けど、とりあえずあとまわし。 ■ メール送ったぜページ
app/views/account/signup_notification.rhtml
メールを送信しました。■ 完了しますたページ
app/views/account/activate.rhtml
ようこそ <%= self.current_user.login %> さん! ユーザー登録が完了しました。■ わすれちゃだめなのが、ログイン前にはみられちゃいやんなページはfilterかける。
class HogeController < ApplicationController include AuthenticatedSystem before_filter :login_required end
4. 疑問
■ logged_in? ってヘルパーはどっから来た?
<h3>Welcome user</h3>
<% if logged_in? %>
<p>Welcome, <%= self.current_user.login %></p>
<% else %>
<% end %>
■ 他のモデルからセッションのユーザー情報にアクセスする方法がわからない
=> テストしにくくなるから他のモデル内からセッション情報に
アクセスしない方がいい?
logged_in? ってヘルパーはどっから来た?
lib/authenticated_system.rb
内で定義されてました。
メールのアクティベーション参考にさせて頂きました。
ありがとうございます。
ひとつ気になったのですが、AccountControllerのactivateメソッドの一行目で
@user = User.find_by_activation_code(params[:id])
となっております。
一度、アクティベーションが完了した場合、カラム内はnullになりますので、params[:id]がnull(存在しない)場合に、予期せぬユーザのオブジェクトが取得できてしまいます。