除非 params[:userid] 是整数,否则如何防止页面呈现?

How can I prevent a page from rendering unless params[:userid] is an Integer?

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

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

这是我正在尝试做的事情:

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

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

Started GET "/" for 127.0.0.1 at 2015-09-28 23:04:24 -0400 ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations" Processing by PagesController#home as HTML Rendered pages/home.html.erb within layouts/application (1.1ms) Completed 200 OK in 124ms (Views: 117.6ms | ActiveRecord: 0.0ms)

Started GET "/" for 127.0.0.1 at 2015-09-28 23:04:31 -0400 Processing by PagesController#home as HTML Rendered pages/home.html.erb within layouts/application (0.0ms) Completed 200 OK in 15ms (Views: 14.9ms | ActiveRecord: 0.0ms)

Started GET "/account/jonathan/settings" for 127.0.0.1 at 2015-09-28 23:04:32 -0400 Processing by AccountController#settings as HTML Parameters: {"userid"=>"jonathan"} Rendered text template (0.0ms) Completed 200 OK in 1ms (Views: 0.8ms | ActiveRecord: 0.0ms)

Started GET "/account/jonathan/settings" for 127.0.0.1 at 2015-09-28 23:04:38 -0400 Processing by AccountController#settings as HTML Parameters: {"userid"=>"jonathan"} Rendered text template (0.0ms) Completed 200 OK in 1ms (Views: 0.2ms | ActiveRecord: 0.0ms)

并且当使用 /account/1/settings 作为路线时:

Started GET "/account/1/settings" for 127.0.0.1 at 2015-09-28 23:27:00 -0400 Processing by AccountController#settings as HTML Parameters: {"userid"=>"1"} Rendered text template (0.0ms) Completed 200 OK in 1ms (Views: 0.2ms | ActiveRecord: 0.0ms)

Started GET "/account/1/settings" for 127.0.0.1 at 2015-09-28 23:27:00 -0400 Processing by AccountController#settings as HTML Parameters: {"userid"=>"1"} Rendered text template (0.0ms) Completed 200 OK in 1ms (Views: 0.2ms | ActiveRecord: 0.0ms)

我试过使用 /account/1/settings/account/jon/settings 等路线,但都没有显示出错误。

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

现在,我要尝试的是添加一些括号以确保人和机器的清晰度:

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

尝试一下,并根据错误消息更新您的答案。

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

您可以在控制器或 Integer 中编写方法 class 并调用它

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

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

问题

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

Im trying to use the param as a way to get a users access token for authentication before being able to access the page, other wise give them an error, or send them to a login page.

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

此外,params hash values are always strings。因此,您当前所做的基于整数的分支将不起作用。

解决方案

使用经过良好测试的 Authentication/Authorization 方案

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

根据经验,您应该使用积极开发并广泛使用的安全性 gem,这样您就可以从所有对其设计有效性和错误进行审查的人员那里受益。除非你有非常令人信服的理由,否则请避免使用低总线因子的安全性 gem。目前,devise is your best bet, but you can select from any widely-adopted authentication or authorizationgem符合您的需求。

修复分支错误

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

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

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

  • before_action :authenticate_user! 处理未经身份验证的用户的重定向。
  • user_signed_in? 到 return 基于当前用户身份验证状态的布尔值。

有关详细信息,请参阅 Controller filters and helpers