我需要简单但完整的指令来实现Devise身份验证策略

时间:2013-02-14 19:51:06

标签: ruby-on-rails authentication devise

我正在尝试编写一个设计身份验证策略来对现有的旧版API进行身份验证。我没有数据库,因此无法从某些现有源迁移用户。我想做点什么:

http://4trabes.com/2012/10/31/remote-authentication-with-devise/

但是,遵循这些说明后,Devise拒绝调用我的身份验证策略。我通过尝试将put调用插入到我的RemoteAuthenticatable模块中来测试这个......

彼得。

编辑按要求添加代码。

应用程序/模型/ User.rb:

class User
  attr_accessor :id

  include ActiveModel::Validations #required because some before_validations are defined in devise
  extend ActiveModel::Callbacks #required to define callbacks
  extend Devise::Models

  define_model_callbacks :validation #required by Devise

  devise :remote_authenticatable
end

lib / remote_authenticatable.rb(注意我插入的puts以获得一些穷人的跟踪)。

module Devise
  module Models
    module RemoteAuthenticatable
      extend ActiveSupport::Concern

      #
      # Here you do the request to the external webservice
      #
      # If the authentication is successful you should return
      # a resource instance
      #
      # If the authentication fails you should return false
      #
      def remote_authentication(authentication_hash)
        puts "In Devise::Models::RemoteAuthenticatable.remote_authentication()"
        # Your logic to authenticate with the external webservice
      end

      module ClassMethods
        ####################################
        # Overriden methods from Devise::Models::Authenticatable
        ####################################

        #
        # This method is called from:
        # Warden::SessionSerializer in devise
        #
        # It takes as many params as elements had the array
        # returned in serialize_into_session
        #
        # Recreates a resource from session data
        #
        def serialize_from_session(id)
          resource = self.new
          resource.id = id
          resource
        end

        #
        # Here you have to return and array with the data of your resource
        # that you want to serialize into the session
        #
        # You might want to include some authentication data
        #
        def serialize_into_session(record)
          [record.id]
        end

      end
    end
  end

  module Strategies
    class RemoteAuthenticatable < Authenticatable
      def valid?
        puts "In Devise::Strategies::RemoteAuthenticatable.valid?()"
        true
      end

      #
      # For an example check : https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/database_authenticatable.rb
      #
      # Method called by warden to authenticate a resource.
      #
      def authenticate!
        puts "In Devise::Strategies::RemoteAuthenticatable.authenticate!()"
        #
        # authentication_hash doesn't include the password
        #
        auth_params = authentication_hash
        auth_params[:password] = password

        #
        # mapping.to is a wrapper over the resource model
        #
        resource = mapping.to.new

        return fail! unless resource

        # remote_authentication method is defined in Devise::Models::RemoteAuthenticatable
        #
        # validate is a method defined in Devise::Strategies::Authenticatable. It takes
        #a block which must return a boolean value.
        #
        # If the block returns true the resource will be loged in
        # If the block returns false the authentication will fail!
        #
        if validate(resource){ resource.remote_authentication(auth_params) }
          success!(resource)
        end
      end
    end
  end
end

以及我添加到config / initializers / devise.rb

的代码
  require 'remote_authenticatable'  

  config.warden do |manager|
     manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
     manager.default_strategies(:scope => :user).unshift :remote
  end

  Devise.add_module :remote_authenticatable, :controller => :sessions,  :route => { :session => :routes }

4 个答案:

答案 0 :(得分:0)

您可以尝试删除对

的调用吗?
manager.strategies.add

而是在策略文件末尾添加此调用

Warden::Strategies.add(:rememberable, Devise::Strategies::RemoteAuthenticatable)

答案 1 :(得分:0)

我将remote_authenticable.rb(模型)添加到app&gt;模型&gt;关注&gt;设计&gt;楷模, 并插入一个调试器语句来检查它是否正确调用

def remote_authentication(authentication_hash)
  debugger
  false 
  # Your logic to authenticate with the external webservice
end

remote_authenticable.rb(策略)进入lib&gt;设计&gt;策略

并将warden块添加到devise.rb(初始化程序)

require "devise/strategies/remote_authenticable.rb"

config.warden do |manager|
  manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
  manager.default_strategies(:scope => :user).unshift :remote
end

它运行......

答案 2 :(得分:0)

在config / initializers / devise.rb中你写了这个

config.warden do |manager|
  manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
  manager.default_strategies(:scope => :user).unshift :remote
end

现在在同一目录中创建另一个文件,即“remote.rb”并添加类似这样的内容

Warden::Strategies.add(:remote) do 
 def valid? 
 true
end 

def authenticate! 

  if params[:user]
    user = User.find_by_login_name(params[:user][:login_name])

    if user && user.account_status != "active" # add your own checks here for authentication 
      fail
      halt! #after this succes no other authentication will process
    end
  else
    fail
  end 
 end
end

答案 3 :(得分:0)

按照相同的教程,这对我有用:

将remote_authenticatable代码分解为: /lib/devise/models/remote_authenticatable.rb和/lib/devise/strategies/remote_authenticatable.rb

在config / initializers / devise.rb中我添加了

require 'devise/orm/active_record'
require "devise/strategies/remote_authenticatable"
require "devise/models/remote_authenticatable"

Devise.add_module :remote_authenticatable, :controller => :sessions, :route => { :session => :routes }

并在Devise.setup下:

config.warden do |manager|
 manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
 manager.default_strategies(:scope => :user).unshift :remote
end