我正在尝试编写一个设计身份验证策略来对现有的旧版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 }
答案 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