acts_as_authenticated を試してみた。

| | コメント(2)
LoginEngine が使えなくて困ってたらacts_as_authenticatedがいいらしいってことで試してみたのでメモ。 > komagata さんありがとうございます!

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]
 @from
YOURSITE の部分をどうすればいいのかわからん。

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 %>
■ 他のモデルからセッションのユーザー情報にアクセスする方法がわからない => テストしにくくなるから他のモデル内からセッション情報に アクセスしない方がいい?

カテゴリ

 

コメント(2)

matake :

logged_in? ってヘルパーはどっから来た?

lib/authenticated_system.rb

内で定義されてました。

メールのアクティベーション参考にさせて頂きました。
ありがとうございます。

ひとつ気になったのですが、AccountControllerのactivateメソッドの一行目で
@user = User.find_by_activation_code(params[:id])
となっております。

一度、アクティベーションが完了した場合、カラム内はnullになりますので、params[:id]がnull(存在しない)場合に、予期せぬユーザのオブジェクトが取得できてしまいます。

コメントする

このブログ記事について

このページは、が2007年7月 5日 00:16に書いたブログ記事です。

ひとつ前のブログ記事は「Rails 1.2 では LoginEngine は使えない?」です。

次のブログ記事は「ビリーズブートキャンプ でカニ!カニ!」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。