【ruby on rails】acts_as_authenticatedで認証
acts_as_authenticatedを使ってユーザ登録を実装してみる。
参考:
http://eringi.com/weblog/archives/2007/07/acts_as_authenticated.html
http://todoer.com/staff/hoti/2007/07/31/acts_as_authenticated%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/
以下のプラグインをインスコ
$ ruby script/plugin discover
$ ruby script/plugin install acts_as_authenticated
discoverってのが何者なのかよく分かってない。
modelとcontrollerの作成
$ ./script/generate authenticated user account
ユーザテーブルの作成
$ rake db:migrate
これだけで、サインアップ、ログイン、ログアウトは可能
http://hogehoge/account/signup
http://hogehoge/account/login
http://hogehoge/account/logout
メールを使って本人性確認するには
authenticated_mailerコントロールの作成
$ ./script/generate authenticated_mailer user
config/environment.rbに以下を追加
Rails::Initializer.run do |config| config.active_record.observers = :user_observer end
sendmailを利用する設定をconfig/environments/development.rbに追加
ActionMailer::Base.delivery_method = :sendmail
ユーザテーブルにアカウントのアクティベーションに関するカラムを追加
$ ./script/generate migration AddUserColumn
data/migrate/xxx_add_user_column.rbを以下のように修正
class AddUserColumn < 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
マイグレートしてDBに反映
$ rake db:migrate
Userモデルを下記に変更
require 'digest/sha1'
class User < ActiveRecord::Base
before_create :make_activation_code
# Virtual attribute for the unencrypted password
attr_accessor :password
validates_presence_of :login, :email
validates_presence_of :password, :if => :password_required?
validates_presence_of :password_confirmation, :if => :password_required?
validates_length_of :password, :within => 4..40, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?
validates_length_of :login, :within => 3..40
validates_length_of :email, :within => 3..100
validates_uniqueness_of :login, :email, :case_sensitive => false
before_save :encrypt_password
# Authenticates a user by their login name and unencrypted password. Returns the user or nil.
def self.authenticate(login, password)
# u = find_by_login(login) # need to get the salt
u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]
u && u.authenticated?(password) ? u : nil
end
# Activates the user in the database.
def activate
@activated = true
update_attributes(:activated_at => Time.now.utc, :activation_code => nil)
end
# Returns true if the user has just been activated.
def recently_activated?
@activated
end
# Encrypts some data with the salt.
def self.encrypt(password, salt)
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end
# Encrypts the password with the user salt
def encrypt(password)
self.class.encrypt(password, salt)
end
def authenticated?(password)
crypted_password == encrypt(password)
end
def remember_token?
remember_token_expires_at && Time.now.utc < remember_token_expires_at
end
# These create and unset the fields required for remembering users between browser closes
def remember_me
self.remember_token_expires_at = 2.weeks.from_now.utc
self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
save(false)
end
def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end
protected
# before filter
def encrypt_password
return if password.blank?
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
self.crypted_password = encrypt(password)
end
def password_required?
crypted_password.blank? || !password.blank?
end
# If you're going to use activation, uncomment this too
def make_activation_code
self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
end
end
accountコントローラを修正
class AccountController < ApplicationController
# Be sure to include AuthenticationSystem in Application Controller instead
include AuthenticatedSystem
# If you want "remember me" functionality, add this before_filter to Application Controller
before_filter :login_from_cookie
# say something nice, you goof! something sweet.
def index
redirect_to(:action => 'signup') unless logged_in? || User.count > 0
end
def login
return unless request.post?
self.current_user = User.authenticate(params[:login], params[:password])
if logged_in?
if params[:remember_me] == "1"
self.current_user.remember_me
cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
end
redirect_back_or_default(:controller => '/account', :action => 'index')
flash[:notice] = "Logged in successfully"
end
end
def signup
@user = User.new(params[:user])
return unless request.post?
@user.save!
# activateする前にログインさせない。
# self.current_user = @user
# 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 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
def logout
self.current_user.forget_me if logged_in?
cookies.delete :auth_token
reset_session
flash[:notice] = "You have been logged out."
redirect_back_or_default(:controller => '/account', :action => 'index')
end
end
ログインが必要なコントローラにbefore_filterを追加
class xxxxController < ApplicationController include AuthenticatedSystem before_filter :login_required end
以上で完了
このログへのコメント(0件)
コメント投稿フォーム
トラックバック
関連ログ
- 【ruby on rails】submit_tagに確認ダイアログをつける方法
- 【ruby on rails】file_columnを使った画像ファイルのアップロード
- 【ruby on rails】railsのHTMLヘルパーに悩む
- 【ruby on rails】rubyでRSSを生成する。
- 【ruby on rails】改行コードをBRコードに変換するには
- 【ruby on rails】start_form_tag / form_tag
- 【ruby on rails】link_toヘルパーにclassを指定するには
- 【ruby on rails】rake db:migrate
- rubyでのメールアドレスとURLを抽出する正規表現
- 【ruby on rails】image_uploadプラグイン
