ruby-on-rails - Rails - 每个请求的数据库连接,基于用户凭据

标签 ruby-on-rails session exchangewebservices

我们有以下问题:我们的应用程序通过其交换 Web 服务 (EWS) 与交换接口(interface),您可以将其视为只是一个花哨的数据库。
例如,我们有一个 Appointment 模型,它应该与 Exchange 上的日历同步。现在 EWS 要求每个连接的用户凭据。这会产生两个问题:

  • 我们如何获得每个请求的用户凭据?
  • 模型应该如何与 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/

    相关文章:

    ruby-on-rails - 如何加快 bundle 安装?

    ruby-on-rails - Rails 4, order in has_many :through. 它什么都不做

    ruby-on-rails - Rails 数据库,为什么在开发和生产中使用相同的 DBMS?

    session - 即使超时设置为 1 小时,Google Analytics session 也会超时?

    c# - EWS 创建约会以换取额外的自定义属性

    java - 如何使用 java ews api 将电子邮件标记为已读

    python - 使用 Exchangelib 过滤帐户中所有文件夹中的邮件

    ruby-on-rails - rails : Is it bad practice to handle CRUD operations for two models in one Controller?

    PHP 从另一个页面获取值

    PHP 没有在 session_start() 上创建 $_SESSION 变量;