我们有以下问题:我们的应用程序通过其交换 Web 服务 (EWS) 与交换接口,您可以将其视为只是一个花哨的数据库。例如,我们有一个 Appointment 模型,它应该与 Exchange 上的日历同步。现在 EWS 要求每个连接的用户凭据。这会产生两个问题:
- 我们如何获得每个请求的用户凭据?
- 模型应该如何与 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
我对处理这种情况的替代和/或更好的设计感兴趣。
有什么想法/建议吗?