【问题标题】:Rails 4.1.5 omniauth strong parametersRails 4.1.5 omniauth 强参数
【发布时间】:2014-08-20 07:49:56
【问题描述】:

将 Rails 4.1.4 升级到 4.1.5 后,我的 facebook omniauth 会话出现错误,此后一切正常。 当我创建一个用户会话时,我得到一个ActiveModel::ForbiddenAttributesError

路线:

  match 'auth/:provider/callback', to: 'sessions#create', as: 'signin', via: :get

会话#创建控制器:

  def create
        user = User.from_omniauth(env["omniauth.auth"])
        session[:user_id] = user.id 
        session[:user_name] = user.name

      redirect_to root_path
  end

还有这样的用户模型:

  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create.tap do |user|
      user.provider ||= auth.provider 
      user.uid = auth.uid
      user.name = auth.info.name
      user.save
    end
  end

我可以通过添加许可来绕过 ActiveModel 错误!我的用户模型中的方法是这样的:

where(auth.slice(:provider, :uid).permit!).first_or_create.tap do |user|

但它会覆盖数据库中的第一个用户... session[:user_id] 似乎总是数据库中的第一个用户。

我不知道这是一个强参数问题、Omniauth 问题还是两者兼而有之?

【问题讨论】:

  • 你还有这个问题吗?
  • 我也有这个问题。从 Rails 4.1.5 降级到 4.1.4,问题就消失了。

标签: ruby-on-rails facebook strong-parameters omniauth-facebook


【解决方案1】:

替换您当前的查找器:

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.provider = auth.provider 
    user.uid      = auth.uid
    user.name     = auth.info.name
    user.save
  end
end

【讨论】:

  • 你能告诉我们为什么会这样吗?
  • 我似乎没有 auth.provider 方法,但我可以使用 auth[:provider] 代替。我猜 Rails 团队阻止了 slice 被用作强参数的旁路。
  • ^ 这似乎是这样做的正当理由。我还发现有时我需要使用auth[:provider]
【解决方案2】:

我详细记录了这里发生的事情:

Rails 4.1.5 Security Fix Breaks Model.where(attributes)

片段:

哎呀! Rails 4.1.5 要求您对 is_a 的任何参数使用安全参数。哈希 例如,如果您在执行 Model.where 时使用 slice 从派生自 Hash 的某个对象中取出一些键,那么当您从 Rails 4.1.4 迁移到 Rails 4.1.5 时,您的代码将抛出此错误:

在 omniauth_callbacks#facebook 中发生 ActiveModel::ForbiddenAttributesError: ActiveModel::ForbiddenAttributesError

【讨论】:

  • 所以我们不能再使用where(some_hash.slice(:attribute1, :attribute2)了?这是一个很好的语法......
  • 它只是变成where(provider: auth.provider, uid: auth.uid),假设您将omniauth json 信息auth 传递到方法中。它仍然像以前一样漂亮。
【解决方案3】:

我的解决方案是这样的。

# extend the object and add method
auth_hash_extended = auth.slice(:provider, :uid)
def auth_hash_extended.permitted?()
  true
end

where( auth_hash_extended ).first_or_create do |user|
    user.provider = auth.provider
    #blablabla
end

如果你很难将哈希分离成键值集,你可以使用这种方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2013-12-07
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多