扩展设计使用远程登录 [英] Extending Devise to use remote login
问题描述
我正在尝试追踪此博客文章允许远程认证与设计,但我无法弄清楚几件事情。
I'm trying to follow this blog post to allow remote authentication with devise, but I can't figure out a few things.
我怎样称呼我的新文件,我在哪里放它们?
What do I call my new files, and where do I put them?
第一个, Devise :: Models :: RemoteAuthenticatable
我假设我调用remote_authenticatable.rb并放入我的模型文件夹中的devise文件夹?
The first one, Devise::Models::RemoteAuthenticatable
I assume I call remote_authenticatable.rb and put in a devise folder in my models folder?
第二个文件Devise的守护者策略我不知道该叫什么,或者放在哪里。
The second file, "Warden strategy for Devise" I have no idea what to call it, or where to put it.
任何想法?我发现教程很不完整。它与Devise指令相关联,作为这样做的方式。
Any ideas? I found the tutorial pretty incomplete. It's linked to from the Devise instructions as the way to do this.
编辑:
我一直在做更多的阅读,我不知道我需要做什么那个博文里说的是什么我一直在尝试将PUT数据简单地传递给我的Rails应用程序,但无法获得任何工作。执行PUT请求会导致身份验证失败。
I've been doing more reading, and I'm not sure I need to do what it says in that blog post. I've been trying to simply PUT data to my Rails app, but can't get anything to work. Doing a PUT request causes devise to loose authentication.
推荐答案
我知道这个问题是多年以前,不完整,最近我花了几天试图让远程身份验证工作。所以我会提供我的解决方案,以防它在将来帮助某人。我使用的是Ruby 2.2.2和Rails 4.2.5.1。
I know this question is years old, but I also found the tutorial to be incomplete, and I recently spent a couple days trying to get remote authentication to work. So I will provide my solution in case it helps someone in the future. I am using Ruby 2.2.2 and Rails 4.2.5.1.
首先,这个 gist 对我来说是非常有帮助的参考。
First of all, this gist was an EXTREMELY helpful reference for me.
我还使用gem fakeweb
来模拟API调用。
I also used the gem fakeweb
to mock API calls.
这是我的文件的样子:
class User < include ActiveModel::Model
# required because some before_validations are defined in devise
include ActiveModel::Validations
# required to define callbacks
extend ActiveModel::Callbacks
# taken from http://stackoverflow.com/questions/8936906/whats-the-correct-way-to-make-before-validation-etc-work-in-an-activemodel
include ActiveModel::Validations::Callbacks
extend Devise::Models
# create getter and setter methods internally for the fields below
attr_accessor :email, :auth_token
#required by Devise
define_model_callbacks :validation
devise :remote_authenticatable, :timeoutable
# Latest devise tries to initialize this class with values
# ignore it for now
def initialize(options={})
end
end
lib / models / remote_authenticatable.rb
lib/models/remote_authenticatable.rb
require 'fakeweb' #used for mocking API calls
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)
FakeWeb.register_uri(:get, "http://localhost:3000/webservice/login.json",
:body => "{ \"success\": \"true\", \"auth_token\": \"secure_token_123\", \"email\": \"bob@1123.com\"}")
# Your logic to authenticate with the external webservice
response = Net::HTTP.get(URI.parse("http://localhost:3000/webservice/login.json"))
self.email = JSON.parse(response)["email"]
self.auth_token = JSON.parse(response)["auth_token"]
return self
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(data, salt)
resource = self.new
resource.email = data['email']
resource.auth_token = data['auth_token']
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)
[
{
:email => record.email,
:auth_token => record.auth_token
},
nil
]
end
end
end
end
end
config / initializers / remote_authenticatable.rb
config/initializers/remote_authenticatable.rb
module Devise
module Strategies
class RemoteAuthenticatable < Authenticatable
#
# 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!
#
# 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 logged in
# If the block returns false the authentication will fail!
#
# resource = resource.remote_authentication(auth_params)
if validate(resource){ resource = resource.remote_authentication(auth_params) }
success!(resource)
end
end
end
end
end
config / initializers / devise.rb
config/initializers/devise.rb
Devise.setup do |config|
# ...
# ...
# OTHER CONFIGURATION CODE HERE
# ...
# ...
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
#
# config.warden do |manager|
# manager.intercept_401 = false
# manager.default_strategies(scope: :user).unshift :some_external_strategy
# end
# BEGIN code that was added to this file
config.warden do |manager|
manager.strategies.add(:remote_authenticatable, Devise::Strategies::RemoteAuthenticatable)
manager.default_strategies(:scope => :user).unshift :remote_authenticatable
end
Devise.add_module :remote_authenticatable, :controller => :sessions, :route => { :session => :routes }
# END code that was added to this file
# ...
# ...
# OTHER CONFIGURATION CODE HERE
# ...
# ...
end
config / application.rb
config/application.rb
# ...
# ...
# OTHER CODE HERE
# ...
# ...
module RemoteAuth
class Application < Rails::Application
# ...
# OTHER CODE HERE
# ...
# BEGIN code that was added to this file
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
# END code that was added to this file
end
end
这篇关于扩展设计使用远程登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!