【问题标题】:How can I prevent a page from rendering unless params[:userid] is an Integer?除非 params[:userid] 是整数,否则如何防止页面呈现?
【发布时间】:2015-12-26 09:41:33
【问题描述】:

我试图阻止页面显示,除非 params[:userid] 是整数。

我知道代码正在被调用,因为它没有抛出错误,也没有渲染,我手动告诉它渲染,然后不渲染来检查。

这是我用来尝试的方法:

render nothing: true unless params[:userid].is_a? Integer

通过快速阅读 Rails,这应该可行,至少在理论上我想是这样。路线设置正确,因为我检查了它并让页面读回:userid。控制台没有抛出任何错误,但这里是使用/account/jonathan/settings 作为路由时的读数:

在 2015-09-28 23:04:24 -0400 开始为 127.0.0.1 获取“/” ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations" PagesController#home 处理为 HTML 在布局/应用程序中渲染页面/home.html.erb (1.1ms) 在 124 毫秒内完成 200 次 OK(查看次数:117.6 毫秒 | ActiveRecord:0.0 毫秒)

在 2015-09-28 23:04:31 -0400 开始为 127.0.0.1 获取“/” PagesController#home 处理为 HTML 在布局/应用程序中渲染页面/home.html.erb (0.0ms) 在 15 毫秒内完成 200 次 OK(查看次数:14.9 毫秒 | ActiveRecord:0.0 毫秒)

在 2015-09-28 23:04:32 -0400 开始为 127.0.0.1 获取“/account/jonathan/settings” AccountController#settings 处理为 HTML 参数:{"userid"=>"jonathan"} 渲染文本模板(0.0ms) 1ms 内完成 200 OK (Views: 0.8ms | ActiveRecord: 0.0ms)

在 2015-09-28 23:04:38 -0400 开始为 127.0.0.1 获取“/account/jonathan/settings” AccountController#settings 处理为 HTML 参数:{"userid"=>"jonathan"} 渲染文本模板(0.0ms) 1ms 内完成 200 OK (Views: 0.2ms | ActiveRecord: 0.0ms)

当使用/account/1/settings 作为路由时:

于 2015-09-28 23:27:00 -0400 开始为 127.0.0.1 获取“/account/1/settings” AccountController#settings 处理为 HTML 参数:{"userid"=>"1"} 渲染文本模板(0.0ms) 1ms 内完成 200 OK (Views: 0.2ms | ActiveRecord: 0.0ms)

于 2015-09-28 23:27:00 -0400 开始为 127.0.0.1 获取“/account/1/settings” AccountController#settings 处理为 HTML 参数:{"userid"=>"1"} 渲染文本模板(0.0ms) 1ms 内完成 200 OK (Views: 0.2ms | ActiveRecord: 0.0ms)

我尝试过使用/account/1/settings/account/jon/settings 之类的路由,但都没有显示出什么问题。

【问题讨论】:

  • {"userid"=>"jonathan"} 中,值是一个字符串。那么,有什么问题呢?
  • @CodeGnome 即使将 Jonathan 替换为 1,它仍然永远不会呈现
  • 因为"1" 也是一个字符串。这整个问题似乎是一个 X/Y 问题。您真正想通过基于params[:userid] 的条件渲染来解决什么功能问题?
  • 我试图使用参数作为一种方式来获取用户访问令牌以进行身份​​验证,然后才能访问该页面,否则会给他们一个错误,或者将他们发送到登录页面。跨度>
  • 1) 这是不安全的。不要滚动您自己的身份验证;使用设计或类似的。 2) 如果您不关心真正的安全性:redirect_to :login if params[:userid].blank? 确保存在 userid

标签: ruby-on-rails ruby-on-rails-4 boolean-expression


【解决方案1】:

问题

您正在尝试根据参数哈希中是否存在值进行重定向。根据上述your comment,您要解决的真正根本问题是:

我试图使用参数作为一种方式来获取用户访问令牌以进行身份​​验证,然后才能访问该页面,否则会给他们一个错误,或者将他们发送到登录页面。

什么都不渲染是不行的。即使逻辑按照您设想的方式成功,也不会重定向它们。

此外,params hash values are always strings。因此,您目前所做的基于整数的分支将无法正常工作。

解决方案

使用经过充分测试的身份验证/授权方案

身份验证和授权方案很难正确。虽然您应该根据应用程序的需要随意应用它们,但滚动您自己的身份验证机制通常是一个非常糟糕的主意。

根据经验,您应该使用积极开发并广泛使用的安全 gem,这样您就可以从所有对其设计有效性和错误进行审查的人那里受益。除非您有非常令人信服的理由,否则请避免使用总线因素较低的安全宝石。目前,devise 是您的最佳选择,但您可以从任何广泛采用的 authenticationauthorization gem 中进行选择,以满足您的需求。

修复分支错误

如果您并不真正关心安全性,只想修复分支逻辑,您可以调用String#blank? 来确定params[:userid] 是否有值。例如:

redirect_to :login if params[:userid].blank?

如果您已经实现了设计,那么有许多助手可以为您处理这些事情,例如:

  • before_action :authenticate_user! 为未经身份验证的用户处理重定向。
  • user_signed_in? 根据当前用户的身份验证状态返回一个布尔值。

请参阅Controller filters and helpers 了解更多详情。

【讨论】:

  • 我会研究更多设计。我已经习惯了 PHP 并且通过指南滚动了一些 auth,但是我正在观看的教程并没有过多地讨论控制流或参数,所以我边走边尝试。
【解决方案2】:

下次粘贴您的错误消息以获得更简单的帮助。

现在,我将尝试添加一些括号以提高人和机器的清晰度:

render(nothing: true) unless params[:userid].is_a?(Integer)

试试这个并用错误消息更新你的答案。

【讨论】:

  • 我没有收到任何错误,但我会在这里粘贴从控制台读取的内容。我的 IDE 在某些语句周围显示了关于括号的警告,所以我认为最好的做法是不使用它们
【解决方案3】:

我认为 params[:userid] 是一个字符串,比如params = {userid: "1"}

您可以在控制器或整数类中编写方法并调用它

render nothing: true unless is_integer?(params[:userid])

protected
def is_integer?(value)
  value.to_s.to_i == value
end

【讨论】:

  • 它仍然没有渲染任何东西
  • userid = "jonathan",它不是一个整数,所以什么都不渲染是正确的。但是/account/1/settings 应该可以,你能发布你的settings 操作吗
  • 没错,但是当用 1 之类的数字替换 jonathan 时,它仍然不会呈现
猜你喜欢
  • 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
相关资源
最近更新 更多