设计设置current_user时如何选择属性?

问题描述 投票:0回答:2

此时,我不确定 helper current_user 的加载方式或位置。我只想从用户表中选择某些属性,但设计为

select * from users
桌子

我想做像

select (id, email, additional_stuff) from users

这样的事情

我希望能够通过设计修改 current_user 集,以便我可以从安全点优化我的应用程序。

使用 Rails 版本 7.0.4 RUby 版本 3.1.3

ruby-on-rails devise
2个回答
0
投票

Devise 建立在 Warden gem 之上,处理实际验证用户的繁重工作。

从数据库中获取用户是通过

Warden::Manager.serialize_from_session
方法完成的,该方法可以重新配置。

# app/initializers/devise.rb
config.warden do |manager|
  manager.serialize_from_session(:users) do |id|
    User.select(:id, :email, :additional_stuff)
        .find(id)
  end
end

但是,我非常怀疑这是否会对安全性有任何真正的好处,并且您很可能最终只会破坏 Devise 的一部分/应用程序的其余部分。例如,除非您加载密码摘要,否则验证用户密码更新可能会失败。

确保你有测试覆盖你的整个 Devise 实现,然后再胡闹它。

很难知道“应用程序中的某些类使用 current_user 对象,其中一个类是模板创建者”实际上是什么意思。但这本身就是一个巨大的安全漏洞。如果这是来自用户的运行代码,它不应该访问整个视图上下文(例如

current_user
方法)。如果用户有权访问实际对象,那么是什么阻止他们查询和获取任何丢失的数据?

如果你真的需要这个特性,你应该在一个单独的渲染器中将它沙盒化(而不是使用 Rails 内置渲染方法),它只能访问你明确传递的上下文和数据(比如代表用户的结构或装饰器),这被认为安全


0
投票

我正在做同样的事情来尝试避免在每次页面加载时加载我们的用户介绍。我尝试了 max 的回答,但由于某种原因它并没有真正起作用。

我正在做的是覆盖 user.rb 类中的 serialize_from_cookie 和 serialize_from_session 类方法。

他们现在看起来像这样:

#user.rb
def self.serialize_from_cookie(*args)
    id, token, generated_at = *args

    record = select('id, ...').find(id)
    record = record.first if record.kind_of? Array

    #record = to_adapter.get(id)      <- what it used to be

    record if record && record.remember_me?(token, generated_at)
end

def self.serialize_from_session(key, salt)
    record = select('id, ...').find(key.first)
    
    #record  = to_adapter.get(key) <- what it used to be
    
    record if record && record.authenticatable_salt == salt
end

似乎有效!这不包括初始登录,这可能会覆盖不同的方法,但它适用于大多数页面加载。如果你有多个范围,你可能想把它包装成一个问题。

© www.soinside.com 2019 - 2024. All rights reserved.