我剛剛將我的當前應用程序中的Restful_Authentication遷移到Devise。我在我的模型文件中將crypted_password的變量更改爲encrypted_password和salt更改爲password_salt,以便兩個密碼相匹配,當我將它們放入放入節目時。我已經按照https://github.com/plataformatec/devise/wiki/How-To:-Migrate-from-restful_authentication-to-Devise-上的教程進行了學習,但user_signed_in?返回模型假,CURRENT_USER返回true,但不能讓ID ...以下是我的模型:Restful_Authentication每次設計無效的密碼
require 'digest/sha1'
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :confirmable, :validatable,
:encryptable, :encryptor => :restful_authentication_sha1
#attr_accessor :password
#set_table_name 'users'
#validates :login, :presence => true,
# :uniqueness => true,
# :length => { :within => 3..40 },
# :format => { :with => Authentication.login_regex, :message => Authentication.bad_login_message }
#validates :name, :format => { :with => Authentication.name_regex, :message => Authentication.bad_name_message },
# :length => { :maximum => 100 },
# :allow_nil => true
#validates :email, :presence => true,
# :uniqueness => true,
# :format => { :with => Authentication.email_regex, :message => Authentication.bad_email_message },
# :length => { :within => 6..100 }
validates_presence_of :login, :email, :first_name, :last_name, :user_type
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, :case_sensitive => false
before_save :encrypt_password
before_create :make_activation_code
# HACK HACK HACK -- how to do attr_accessible from here?
# prevents a user from submitting a crafted form that bypasses activation
# anything else you want your user to change should be added here.
has_many :assets
attr_accessible :login, :email, :name, :password, :password_confirmation
class UserType
ADMIN = 'Admin'
UPDATER = 'Updater'
VIEWER = 'Viewer'
end
def self.GetUserTypes
usertypes = [UserType::ADMIN, UserType::UPDATER, UserType::VIEWER]
return usertypes
end
has_many :assets
# Authenticates a user by their login name and unencrypted password. Returns the user or nil.
#
# uff. this is really an authorization, not authentication routine.
# We really need a Dispatch Chain here or something.
# This will also let us return a human error message.
#
def activate
@activated = true
self.activated_at = Time.now.utc
self.activation_code = nil
save(false)
end
def active?
# the existence of an activation code means they have not activated yet
activation_code.nil?
end
def self.authenticate(login, password)
puts ("===IN AUTHENTICATE===")
return nil if login.blank? || password.blank?
u = find_by_login(login.downcase) # need to get the salt
u && u.authenticated?(password) ? u : nil
end
#def destroy
# puts ("**********In User Model destroy")
#end
def login=(value)
write_attribute :login, (value ? value.downcase : nil)
end
def email=(value)
write_attribute :email, (value ? value.downcase : nil)
end
def authenticated?(password)
puts ("IN AUTHENTICATED?")
encrypted_password == encrypt(password)
end
def encrypt(password)
self.class.encrypt(password, password_salt)
end
def self.encrypt(password, password_salt)
Digest::SHA1.hexdigest("--#{password_salt}--#{password}--")
end
def get_name_last_first
return last_name + ", " + first_name
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
remember_me_for 2.weeks
end
def remember_me_for(time)
remember_me_until time.from_now.utc
end
def remember_me_until(time)
self.remember_token_expires_at = time
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
# Returns true if the user has just been activated.
def recently_activated?
@activated
end
protected
# before filter
def encrypt_password
return if password.blank?
self.password_salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
self.encrypted_password = encrypt(password)
end
def password_required?
encrypted_password.blank? || !password.blank?
end
def make_activation_code
self.activation_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join)
end
end
和我的控制器之一:
class AssetsController < ApplicationController
before_filter :validate_user_type, :except => [:myassets, :show]
# GET /assets
# GET /assets.xml
def index
# check incoming page param, if not present, set it to 1
searchPage = 1
if params[:page] != nil
searchPage = params[:page]
end
#@assets = Asset.find(:all, :order => "asset_id ASC")
@assets = Asset.paginate(:per_page => 25, :page => searchPage, :order => "asset_id ASC")
# setup the action menu options
@actionMenuOptions = []
option1 = ActionMenuOption.new("My Assets", assets_path + "/myassets", User::UserType::UPDATER)
option2 = ActionMenuOption.new("New Asset", new_asset_path, User::UserType::UPDATER)
option3 = ActionMenuOption.new("Export to Excel", assets_path + "/exporttoexcel.csv", User::UserType::UPDATER)
@actionMenuOptions[0] = option1
@actionMenuOptions[1] = option2
@actionMenuOptions[2] = option3
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @assets }
format.csv { render :csv => @assets }
end
end
# GET /assets/exporttoexcel.csv
def exporttoexcel
@assets = Asset.find(:all, :order => "asset_id ASC")
# we should never call this action without the .csv added
respond_to do |format|
#format.html # index.html.erb
#format.xml { render :xml => @assets }
format.csv { render :csv => @assets }
end
end
# GET assets/myassets
# GET assets/myassets.xml
def myassets
# check incoming page param, if not present, set it to 1
searchPage = 1
if params[:page] != nil
searchPage = params[:page]
end
#@assets = Asset.find(:all, :conditions => { :user_id => current_user.id }, :order => "asset_id ASC")
@assets = Asset.paginate(:conditions => { :user_id => current_user.id }, :per_page => 25, :page => searchPage, :order => "asset_id ASC")
respond_to do |format|
format.html # myassets.html.erb
format.xml { render :xml => @assets }
format.csv { render :csv => @assets }
end
end
# GET /assets/1
# GET /assets/1.xml
def show
@asset = Asset.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @asset }
end
end
# GET /assets/new
# GET /assets/new.xml
def new
@asset = Asset.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @asset }
end
end
# GET /assets/1/edit
def edit
@asset = Asset.find(params[:id])
end
# POST /assets
# POST /assets.xml
def create
@asset = Asset.new(params[:asset])
@asset.last_status_update = Time.now
respond_to do |format|
if @asset.save
flash[:notice] = 'Asset was successfully created.'
format.html { redirect_to :controller => 'assets', :action => 'index' }
format.xml { render :xml => @asset, :status => :created, :location => @asset }
else
format.html { render :action => "new" }
format.xml { render :xml => @asset.errors, :status => :unprocessable_entity }
end
end
end
# PUT /assets/1
# PUT /assets/1.xml
def update
@asset = Asset.find(params[:id])
# check to see if the last status update needs to be updated
if @asset.status_id != params[:asset][:status_id] ||
@asset.user_id != params[:asset][:user_id] ||
@asset.location_id != params[:asset][:location_id]
puts "*** Changing last status update... ****"
@asset.last_status_update = Time.now
end
respond_to do |format|
if @asset.update_attributes(params[:asset])
flash[:notice] = 'Asset was successfully updated.'
format.html { redirect_to :controller => 'assets', :action => 'index' }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @asset.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /assets/1
# DELETE /assets/1.xml
def destroy
@asset = Asset.find(params[:id])
@asset.destroy
respond_to do |format|
format.html { redirect_to(assets_url) }
format.xml { head :ok }
end
end
# GET assets/search
# GET assets/search
def search
@searchBox = params[:search_field]
# this is very NON-rails'ish' but I needed to perform the join on assets and users so I could
# search user name in the global search, therefore use the find_by_sql call; I had to also use a
# union because the assets may have a null user id in the assigned_to field.
searchSQL = "SELECT a.id, a.asset_id, a.name, a.serial_number, a.category_id, a.status_id, a.user_id, a.location_id" +
" from assets a where a.asset_ID LIKE '%" + @searchBox +
"%' OR a.name LIKE '%" + @searchBox + "%'" +
"UNION " +
"SELECT a.id, a.asset_id, a.name, a.serial_number, a.category_id, a.status_id, a.user_id, a.location_id" +
" from assets a, users u where a.user_id = u.id AND (u.first_name LIKE '%" + @searchBox +
"%' OR u.last_name LIKE '%" + @searchBox + "%')" +
"order by asset_id ASC"
# check incoming page param, if not present, set it to 1
searchPage = 1
if params[:page] != nil
searchPage = params[:page]
end
#@assets = Asset.find_by_sql(searchSQL)
@assets = Asset.paginate_by_sql(searchSQL, :page => searchPage, :per_page => 25)
respond_to do |format|
format.html # search.html.erb
format.xml { render :xml => @assets }
format.csv { render :csv => @assets }
end
end
private
def validate_user_type
if (current_user.user_type == User::UserType::VIEWER)
redirect_to :controller => 'assets', :action => 'myassets'
end
end
end
我使用的是Devise 1.4.0,謝謝我會研究一下。 –
我在Devise 1.3.4上,因爲1.4.0在Rails 3.0.9下不能很好地工作。是的,我登錄後檢查了signed_in?(:user),返回false。我會查看我以前使用restful auth的sessions_controller。我一直使用restful auth將用戶識別爲session [:user_id],並猜測Devise尋找session [:user]而不是session [:user_id]。 – rhetonik
我不知道我做了什麼,但我通過重新安裝刪除資源工作:用戶從我的路線,然後我發現我仍然有restful_authentication片段在那裏,我不得不刪除。 –