我们有以下问题:我们的应用程序通过其交换 Web 服务 (EWS) 与交换接口(interface),您可以将其视为只是一个花哨的数据库。
例如,我们有一个 Appointment 模型,它应该与 Exchange 上的日历同步。现在 EWS 要求每个连接的用户凭据。这会产生两个问题:
我们不想做的是在需要与 EWS 交互的每个操作中询问用户的密码。我们也不想牺牲安全性。
我们目前的解决方案:
我们将来自用户的凭据(我们在登录期间获得)存储在 session 中。
这很难看,因为这意味着用户名和密码存储在客户端计算机上的 cookie 中 - 我知道它是加密的,但它仍然很难看。
然后在 Controller 中,我们懒惰地创建一个 EWS 客户端并将其传递给每个需要与 EWS 交互的模型实例。
这很丑陋,因为这意味着与其他数据库操作不同(您可以将 EWS 视为另一个数据库),这意味着您必须为每个操作执行额外的步骤。
示例(简化/精简):
# app/models/appointments.rb
class Appointment
attr_writer :ews
def pull_from_exchange
exchange_event = ews.events[exchange_id, exchange_change_key]
# …update from exchange_event.to_hash…
self
end
def push_to_exchange
exchange_event = ews.events.new(to_hash_for_exchange)
exchange_event.save
update_attributes(exchange_id: exchange_event.id, exchange_change_key: exchange_event.change_key)
self
end
def ews
raise EwsClientNotProvided unless @ews
@ews
end
def save_and_push!
self.class.transaction do
save!
push_to_exchange
end
end
end
# app/controllers/appointments_controller.rb
class AppointmentsController < ApplicationController
def create
@appointment = Appointment.new(params[:appointment])
@appointment.ews = ews
@appointment.save_and_push!
end
private
def ews
@ews ||= Ews.client(session.slice(:username, :password, :email).merge(endpoint: ews_endpoint))
end
def ews_endpoint
Rails.application.configuration.ews_endpoint
end
end
我对处理这种情况的替代和/或更好的设计感兴趣。
有什么想法/建议吗?
最佳答案
对于数据库连接,我推荐Thread.current[]
在 rackapp 中,伪全局变量有时是必要的。
将用户凭据存储在客户端是最佳解决方案,您可以使用另一种加密方式为密码字段添加趣味,以保护其免受暴力破解。这是因为 cookie 是经过哈希处理的,因此可以暴力破解它,因为可以在本地检查解密成功的位置。如果您将凭据存储在服务器上的某个位置,那么如果服务器被黑客入侵,所有密码都会被泄露。如果您将数据存储在客户端,它们会更安全,因为您需要这两个部分(服务器上的 key 和 cookie)。
关于ruby-on-rails - Rails - 每个请求的数据库连接,基于用户凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11665733/