gpt4 book ai didi

ruby-on-rails - rails : Devise Authentication from an ActiveResource call

转载 作者:行者123 更新时间:2023-12-01 15:50:42 25 4
gpt4 key购买 nike

我的两个 Rails 应用程序(app1、app2)正在使用事件资源进行通信。

app1 调用 app2 在 app2 中创建一个用户。 app2 将创建用户并希望 app1 然后将用户重定向到 app2 的经过身份验证的页面。

从 app1 到 app2 总是会要求用户登录。

我一直在寻找一种方法来避免在 app2 中执行此登录步骤,而是让用户在创建用户的第一个事件资源调用期间登录,并以某种方式获取写入的身份验证 token 。

身份验证是使用 Devise 完成的。 Devise 中是否内置了任何支持此功能的内容?

传递身份验证 token 是可行的方法吗?

最佳答案

您正在尝试实现一种形式的单点登录服务 (SSO)(使用 app1 登录,并自动通过 app2、app3 进行身份验证...)。不幸的是,这不是一项微不足道的任务。您或许可以让它发挥作用(也许您已经做到了),但与其尝试重新发明轮子,不如集成现有解决方案呢?或者更好的是标准协议(protocol)?这实际上相对容易。

CAS 服务器

RubyCAS是实现耶鲁大学 CAS(中央认证服务)协议(protocol)的 Ruby 服务器。我用它取得了巨大的成功。

棘手的部分是让它与您现有的 Devise 身份验证数据库一起使用。我们遇到了同样的问题,在深入研究代码之后,我想出了以下内容,这对我们来说就像一个魅力。这进入你的 RubyCAS 服务器配置,默认为 /etc/rubycas-server/config.yml。当然,根据需要进行调整:

authenticator:
class: CASServer::Authenticators::SQLEncrypted
database:
adapter: sqlite3
database: /path/to/your/devise/production.sqlite3
user_table: users
username_column: email
password_column: encrypted_password
encrypt_function: 'require "bcrypt"; user.encrypted_password == ::BCrypt::Engine.hash_secret("#{@password}", ::BCrypt::Password.new(user.encrypted_password).salt)'

enter code here

encrypt_function 很难理解...我不太喜欢在其中嵌入 require 语句,但是,嘿,它有效。不过,我们欢迎任何改进。

CAS 客户

对于客户端(您将要集成到 app2、app3 中的模块...),RubyCAS-client 提供了一个 Rails 插件 gem 。

您将需要一个初始化程序 rubycas_client.rb,类似于:

require 'casclient'
require 'casclient/frameworks/rails/filter'

CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => "https://cas.example.com/"
)

最后,您可以重新连接一些 Devise 调用以使用 CAS,这样您当前的代码几乎可以按原样工作:

# Mandatory authentication
def authenticate_user!
CASClient::Frameworks::Rails::Filter.filter(self)
end

# Optional authentication (not in Devise)
def authenticate_user
CASClient::Frameworks::Rails::GatewayFilter
end

def user_signed_in?
session[:cas_user].present?
end

很遗憾,没有直接的方法来替换 current_user,但您可以尝试以下建议:

具有直接数据库访问权限的当前用户

如果您的客户端应用程序可以访问后端用户数据库,您可以从那里加载用户数据:

def current_user
return nil if session[:cas_user].nil?
return User.find_by_email(session[:cas_user])
end

但对于更具可扩展性的架构,您可能希望将应用程序与后端分开。对于,您可以尝试以下两种方法。

current_user 使用 CAS extra_attributes

使用 CAS 协议(protocol)提供的 extra_attributes:基本上,将所有必要的用户数据作为 CAS token 中的 extra_attributes 传递(添加 extra_attributes 键,列出所需的属性,到 config.yml),在客户端重建一个虚拟用户。代码看起来像这样:

def current_user
return nil if session[:cas_user].nil?
email = session[:cas_user]
extra_attributes = session[:cas_extra_attributes]
user = VirtualUser.new(:email => email,
:name => extra_attributes[:name],
:mojo => extra_attributes[:mojo],
)
return user
end

VirtualUser 类定义留作练习。提示:使用无表 ActiveRecord(请参阅 Railscast #193)应该可以让您编写一个直接替换,它应该可以与您现有的代码一起工作。

current_user 在后端使用 XML API 和 ActiveResource

另一种可能性是在用户后端准备一个 XML API,然后使用 ActiveResource 来检索您的用户模型。在这种情况下,假设您的 XML API 接受电子邮件参数来过滤用户列表,代码将如下所示:

def current_user
return nil if session[:cas_user].nil?
email = session[:cas_user]
# Here User is an ActiveResource
return User.all(:params => {:email => email}).first
end

虽然此方法需要额外请求,但我们发现它是最灵活的。只要确保保护您的 XML API,否则您可能会在您的系统中打开一个巨大的安全漏洞。 SSL、HTTP 身份验证,并且由于它仅供内部使用,因此加入 IP 限制是一种很好的措施。

奖励:其他框架也可以加入其中!

由于 CAS 是一种标准协议(protocol),因此您可以获得额外的好处,即允许使用其他技术的应用程序使用您的单点登录服务。 Java有官方客户端, PHP , .NetApache .

如果这对您有帮助,请告诉我,如果您有任何问题,请随时提出。

关于ruby-on-rails - rails : Devise Authentication from an ActiveResource call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7503156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com