【问题标题】:Reset scopes set in config/initializers/doorkeeper.rb on Heroku重置 Heroku 上 config/initializers/doorkeeper.rb 中设置的范围
【发布时间】:2016-10-22 00:06:57
【问题描述】:

我正在尝试在我的 OAuth2 服务中创建一个功能,开发人员可以在其中创建、读取和销毁范围,以供使用我的服务的应用程序使用。

为了做到这一点,我创建了一个基本的 Scope 模型,我希望 Doorkeeper 使用用户创建/销毁的任何范围来更新其 @optional_scopes / @scopes。 (注意:只有在不使用时才能销毁作用域。)

注意 (TL;DR):这一切都在开发中完美运行,但在 Heroku 上的生产环境中不起作用——所以问题的关键在于如何更新 Doorkeeper 内部的实例变量,这些实例变量通常是在应用程序初始化时设置....如果可能的话!

我已将初始化程序设置为获取数据库中的所有范围并将它们设置为optional_scopes

config/initializers/doorkeeper.rb:

Doorkeeper.configure do
  ...
  default_scopes :public
  optional_scopes( *Scope.where.not(name: 'public').map{ |s| s.name } )
  ...
end

我的“CRD”范围有一个基本控制器,它有一个过滤器可以在创建或销毁一个范围列表后重置范围列表:

class ScopesController < ApplicationController
  after_action :set_optional_scopes, only: [ :create, :destroy ]
  ...

  def set_optional_scopes
    Doorkeeper.configuration.instance_variable_set(
      '@optional_scopes',
      Scope.where.not(name: 'public').map{ |s| s.name }
    )
  end
end

在我的链接应用程序视图中,我有一个范围循环,它为范围提供用户复选框。 views/doorkeeper/applications/_form.html.erb:

<% Doorkeeper.configuration.optional_scopes.each do |scope| %>
  <%= check_box_tag(
    scope,
    'true',
    application_has_scope?( application, scope.to_s )
  ) %>
  <%= label_tag(
    scope,
    scope.to_s,
    class: 'no-style display-inline-block'
  ) %>
  <br>
<% end %>

注意我是如何调用 Doorkeeper.configuration.optional_scopes 来填充复选框的。

考虑到此代码在 Heroku 实例中的适当更新,我还从以下位置覆盖了 Doorkeeper 的 self.configuration 方法:

module Doorkeeper
  ...
  def self.configuration
    @config || (fail MissingConfiguration)
  end
  ...
end

到:

module Doorkeeper
  def self.configuration
    if @config
      # Reset the scopes every time the config is called
      @config.instance_variable_set(
        '@scopes',
        Scope.all.map{ |s| s.name }
      )
      @config
    else
      (fail MissingConfiguration)
    end
  end
end

所以,正如我上面所说,这在开发中运行良好。但是,在生产中,它无法更新复选框列表,这意味着 Doorkeeper.configuration.optional_scopes 在创建操作后没有得到适当的重置。

非常感谢您的宝贵时间和任何帮助!

【问题讨论】:

    标签: ruby-on-rails heroku doorkeeper


    【解决方案1】:

    好吧,好吧,在写这篇文章的过程中,我放慢了速度,想出了解决方案,就在我眼前……

    在门卫的self.configuration 方法的覆盖中,我需要做的就是重置optional_scopes 而不是scopes,因为scopes 无论如何都被定义为default_scopes + optional_scopes

    所以它看起来像这样:

    def self.configuration
      if @config
        # Reset the scopes every time the config is called
        @config.instance_variable_set(
          '@optional_scopes',
          Scope.where.not(name: 'public').map{ |s| s.name }
        )
        @config
      else
        (fail MissingConfiguration)
      end
    end
    

    由于Doorkeeper::OAuth::Scopes 的超类的NoMethodError,这导致我的所有测试都失败了,然后我意识到我需要重写该方法以包含用于Array 的elsif。所以,这就是那个方法:

    module OAuth
      class Scopes
        def +(other)
          if other.is_a? Scopes
            self.class.from_array(all + other.all)
          elsif other.is_a? Array
            self.class.from_array(all + other)
          else
            super(other)
          end
        end
      end
    end
    

    可以看原文here.

    我希望有一天这一切对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多