1

我是 Rails 的新手,并且在遵循 Lynda.com 教程后一直在 Rails 3 中开发应用程序,其中 Kevin Skoglund 向我们展示了一种使用 SHA1 Digest 对用户进行身份验证的方法。我在我的应用程序中使用了它,现在需要进行一些授权。当我四处搜索时,我发现 CanCan 是更好的 Rails 授权之一。但是,CanCan 似乎主要是使用 Devise 或 Authlogic 身份验证而不是自定义身份验证来实现的。

  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

应用控制器.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
4

1 回答 1

0

我建议首先阅读或观看有关 CanCan 的 Railscast。它是由这个 gem 的作者制作的,因此信息量很大:

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。

于 2012-03-26T14:05:42.870 回答