0

我剛剛將我的當前應用程序中的Restful_Authentication遷移到Devise。我在我的模型文件中將crypted_pa​​ssword的變量更改爲encrypted_pa​​ssword和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 

回答

0

什麼我們來設計的版本,你」重新使用那裏?我正在將我的授權系統從安靜遷移到設計。 user_signed_in?也沒有爲我工作。

但是,signed_in?(:user)正在爲我工​​作。我還沒有在用戶登錄後檢查這種情況,但至少在用戶沒有登錄時返回false。

Ref:http://groups.google.com/group/plataformatec-devise/browse_thread/thread/e87dd5d00ce0217c?pli=1

+0

我使用的是Devise 1.4.0,謝謝我會研究一下。 –

+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

+0

我不知道我做了什麼,但我通過重新安裝刪除資源工作:用戶從我的路線,然後我發現我仍然有restful_authentication片段在那裏,我不得不刪除。 –