我们遇到以下问题:我们的应用程序通过其交换Web服务(EWS)与交换接口,您可以将其视为一个奇特的数据库。 例如,我们有一个约会模型,应该与Exchange上的日历同步。现在,EWS需要每个连接的用户凭据。这会产生两个问题:
我们不想做的是询问用户在需要与EWS交互的每个操作上的密码。我们也不想牺牲安全。
我们目前的解决方案:
我们在会话中存储来自用户(我们在登录期间获得)的凭据。 这很难看,因为这意味着用户名和密码存储在客户端计算机上的cookie中 - 我知道它是加密的,但它仍然很难看。
然后在控制器中,我们懒洋洋地创建一个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
我对替代和/或更好的设计感兴趣来处理这种情况。
有任何想法/建议吗?
答案 0 :(得分:1)
对于数据库连接,我建议在rackapp中使用Thread.current[]
,伪全局变量有时是必要的恶意。
在客户端上存储用户凭据是最佳解决方案,您可以使用另一种加密技术来加密密码字段,以防止暴力破解。这是因为cookie经过哈希处理,因此有可能对其进行强制执行,因为可以检查解密在本地成功的位置。如果将凭据存储在服务器上的某个位置,则在服务器被黑客攻击时会破坏所有密码。如果您在客户端存储数据,则它们更安全,因为您需要两个部分(服务器上的密钥和cookie)。