0

我是Rails的新手,並且在遵循Lynda.com教程(Kevin Skoglund向我們展示使用SHA1摘要驗證用戶的方法)之後開發了rails 3中的應用程序。我在我的應用程序中使用它,現在需要加入一些授權。當我搜索周圍時,我發現CanCan是用於Rails授權的更好的產品之一。但是,CanCan似乎主要使用Devise或Authlogic身份驗證而不是自定義身份驗證來實現。使用CanCan授權以及Rails 3中的自定義身份驗證

  1. 我想知道如果我們使用自定義身份驗證是否可以使用CanCan,就像我一樣。是的,如何讓CanCan工作?
  2. 它看起來像CanCan需要一些'create_user'來存在,但我不知道如何/在哪裏創建它。
  3. 另一種替代方案,我認爲將放在我的每個頁面的自定義檢查,以檢查用戶角色,並重定向到一個錯誤頁面,如果他們是未經授權的,但這似乎是一個不好的方法來解決這個問題...你請在此觀看。
  4. 如果您需要任何其他信息,請讓我知道。我使用Ruby 1.9.3和Rails 3.2.1。

下面是我設置當前身份驗證的方式。任何幫助將不勝感激。

access_controller.rb

class AccessController < ApplicationController 
    before_filter :confirm_logged_in, :except => [:login, :attempt_login, :logout] 

    def attempt_login 
    authorized_user = User.authenticate(params[:username], params[:password]) 
    if authorized_user 
     session[:user_id] = authorized_user.id 
     flash[:notice] = "You are logged in" 
     redirect_to(:controller => 'orders', :action => 'list') 
    else 
     flash[:notice] = "Invalid Username/password combination" 
     redirect_to(:action => 'login') 
    end 
    end 

    def logout 
    session[:user_id] = nil 
    flash[:notice] = "You have been logged out" 
    redirect_to(:action => 'login') 
    end 
end 

user.rb(用戶模型)

require 'digest/sha1' 

    class User < ActiveRecord::Base 
     has_one :profile 
     has_many :user_roles 
     has_many :roles, :through => :user_roles 

     attr_accessor :password 
     attr_protected :hashed_password, :salt 

     def self.authenticate(username="", password="") 
     user = User.find_by_username(username) 
     if user && user.password_match(password) 
      return user 
     else 
      return false 
     end 
     end 

     def password_match(password="") 
     hashed_password == User.hash_with_salt(password, salt) 
     end 

     validates_length_of :password, :within => 4..25, :on => :create 
     before_save :create_hashed_password 
     after_save :clear_password 

     def self.make_salt(username="") 
     Digest::SHA1.hexdigest("Use #{username} with #{Time.now} to make salt") 
     end 

     def self.hash_with_salt(password="", salt="") 
     Digest::SHA1.hexdigest("Put #{salt} on the #{password}") 
     end 

     private 
     def create_hashed_password 
     unless password.blank? 
      self.salt = User.make_salt(username) if salt.blank? 
      self.hashed_password = User.hash_with_salt(password, salt) 
     end 
     end 

     def clear_password 
     self.password = nil 
     end 
    end 

ApplicationController.rb

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    private 

    def confirm_logged_in 
    unless session[:user_id] 
     flash[:notice] = "Please Log In" 
     redirect_to(:controller => 'access', :action => 'login') 
     return false 
    else 
     return true 
    end 
    end 
end 

回答

0

我建議先閱讀或觀看關於CanCan的Railscast。

http://railscasts.com/episodes/192-authorization-with-cancan

您還可以得到GitHub的頁面上的幫助:

https://github.com/ryanb/cancan

不知何故,您需要將當前獲取它通過這種寶石的作者,因此非常豐富的生產登錄用戶。這是current_user方法的作用,它需要在用戶控制器上定義。嘗試這樣的:

class UsersController < ApplicationController 
    # your other actions here 

    def current_user 
    User.find(session[:user_id]) 
    end 
end 

然後,您應該能夠使用上面的資源中所述的CanCan。

+0

謝謝。我確實看過這集,但它已經很老了。我們現在有CanCan 1.6版本,視頻所遵循的版本是1.0左右。所以,我檢查了github網站的最新信息。 [https://github.com/ryanb/cancan]指定CanCan需要在控制器中存在current_user方法。 – Prashanth 2012-03-26 14:17:12

+0

編輯我的答案,希望現在更有幫助 – 2012-03-26 14:18:36

+0

太好了。代碼確實需要一些額外的行來授權每種需要授權的方法 - 「授權! :list,@ user'工作,但你的解決方案工作...作爲任何其他人試圖做類似的事情的一個說明,我不得不將你建議的current_user方法移動到'ApplicationController。rb'而不是在每個控制器中聲明它。我將探討一下如何根據我的需要定製這個功能。 – Prashanth 2012-03-26 15:06:55