【问题标题】:How can Authlogic be used with Mongoid?Authlogic 如何与 Mongoid 一起使用?
【发布时间】:2013-08-15 20:36:42
【问题描述】:

Authlogic 需要许多 Active Record 功能,这些功能在 Active Model 中不可用,因此在 Mongoid 中不可用。 Authlogic如何与Mongoid一起使用?

【问题讨论】:

    标签: ruby-on-rails mongodb mongoid ruby-on-rails-4 authlogic


    【解决方案1】:

    通过猴子修补 Authlogic 可以将 Authlogic 与 Mongoid 一起使用。 YMMV。

    首先,将 Authlogic 和 Mongoid 添加到 Gemfile。

    gem 'mongoid', github: 'mongoid/mongoid' # Currently required for Rails 4
    gem 'authlogic', '~> 3.3.0'
    

    下一个猴子补丁 Authlogic。首先创建目录lib/modules并创建文件lib/modules/login.rb

    # lib/modules/login.rb
    module Authlogic
      module ActsAsAuthentic
        module Login
          module Config
            def find_by_smart_case_login_field(login)
              # Case insensitivity for my project means downcase.
              login = login.downcase unless validates_uniqueness_of_login_field_options[:case_sensitive] 
    
              if login_field
                where({ login_field.to_sym => login }).first
              else
                where({ email_field.to_sym => login }).first
              end
            end
          end
        end
      end
    end
    

    通过编辑 config/application.rb 告诉 rails 加载您的新模块

    # config/application.rb
    module YourApp
      class Application < Rails::Application
        config.autoload_paths += %W(#{config.root}/lib) # ADD THIS
      end
    end
    

    通过创建 config/initializers/authlogic.rb 告诉 rails 需要您的模块并添加一行:

    # config/initializers/authlogic.rb
    require 'modules/login.rb'
    

    下一步是关注可验证性。默认情况下,关注点仅在 Rails 4 中可用。您需要将其直接添加到 Rails 3 中的可验证类中。

    # app/models/concerns/authenticable.rb
    module Authenticable
      extend ActiveSupport::Concern
    
      included do
        include Authlogic::ActsAsAuthentic::Base
        include Authlogic::ActsAsAuthentic::Email
        include Authlogic::ActsAsAuthentic::LoggedInStatus
        include Authlogic::ActsAsAuthentic::Login
        include Authlogic::ActsAsAuthentic::MagicColumns
        include Authlogic::ActsAsAuthentic::Password
        include Authlogic::ActsAsAuthentic::PerishableToken
        include Authlogic::ActsAsAuthentic::PersistenceToken
        include Authlogic::ActsAsAuthentic::RestfulAuthentication
        include Authlogic::ActsAsAuthentic::SessionMaintenance
        include Authlogic::ActsAsAuthentic::SingleAccessToken
        include Authlogic::ActsAsAuthentic::ValidationsScope
      end
    
      def readonly?
        false
      end
    
      module ClassMethods
        def <(klass)
          return true if klass == ::ActiveRecord::Base
          super(klass)
        end
    
        def column_names
          fields.map &:first
        end
    
        def quoted_table_name
          self.name.underscore.pluralize
        end
    
        def default_timezone
          :utc
        end
    
        def primary_key
          if caller.first.to_s =~ /(persist|session)/
            :_id
          else
            @@primary_key
          end
        end
    
        def find_by__id(*args)
          find *args
        end
    
        def find_by_persistence_token(token)
          where(persistence_token: token).first
        end
    
        # Replace this with a finder to your login field
        def find_by_email(email)
          where(email: email).first
        end
    
        def with_scope(query)
          query = where(query) if query.is_a?(Hash)
          yield query
        end
      end
    end
    

    基本上就是这样。这是一个示例User 类。

    # app/models/user.rb
    class User
      include Mongoid::Document
      include Mongoid::Timestamps
    
      include Authenticable
    
      field :name
      field :email
      field :crypted_password
      field :password_salt
      field :persistence_token
      field :single_access_token
      field :perishable_token
    
      field :login_count,        type: Integer, default: 0
      field :failed_login_count, type: Integer, default: 0
      field :last_request_at,    type: DateTime
      field :last_login_at,      type: DateTime
      field :current_login_at,   type: DateTime
      field :last_login_ip
      field :current_login_ip
    
      field :role, type: Symbol, default: :user
    
      index({ name: 1 })
      index({ email: 1 }, { unique: true })
      index({ persistence_token: 1}, { unique: true })
      index({ last_login_at: 1})
    
      validates :name, presence: true
      validates :email, presence: true, uniqueness: true
      validates :crypted_password, presence: true
      validates :password_salt, presence: true
    
      acts_as_authentic do |config|
        config.login_field = 'email' # Remember to add a finder for this
      end
    end
    

    UserSession 将如下所示:

    # app/models/user_session.rb
    class UserSession < Authlogic::Session::Base
      def to_key
        new_record? ? nil : [self.send(self.class.primary_key)]
      end
    
      def to_partial_path
        self.class.name.underscore
      end
    end
    

    应用程序控制器助手与往常一样。

    # app/controllers/application_controller.rb
    class ApplicationController < ActionController::Base
      protect_from_forgery with: :exception
      helper_method :current_user
    
      private
      def current_user_session
        @current_user_session = UserSession.find unless 
          defined?(@current_user_session)
        @current_user_session
      end
    
      def current_user
        @current_user = current_user_session && 
          current_user_session.user unless defined?(@current_user)
        @current_user
      end
    end
    

    就是这样。其他一切都应该像以前一样工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 2016-10-06
      • 2016-03-06
      • 2012-11-18
      相关资源
      最近更新 更多