【问题标题】:Constraining a rails route to only be called internally将 rails 路由限制为仅在内部调用
【发布时间】:2015-11-23 10:15:37
【问题描述】:

在将 Javascript、JQuery 和 AJAX 与 Rails 一起使用时,我们经常有一些内部路由/url,我们可以将它们称为帮助程序。

例如,如果我有一个使用 Twitter Typeahead 的搜索栏,我可能会使用像 /search/suggestions 这样的内部路由,我的 Javascript 可以调用它来预加载一些 typeahead 建议。

如何防止此类路由被外部/公共用户调用?重要的是只有“内部应用程序”才能访问此路由。

我试图限制到本地主机的路由,但运气不佳 -

constraints(ip: /127.0.0.1/) do
    get "/search/suggestions", to: "search#load_suggestions"
end

Rails 抱怨它找不到那条路线,大概是因为限制。

ActionController::RoutingError (No route matches [GET] "/search/suggestions"):
  actionpack (4.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.2.2) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.2) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.2) lib/rails/rack/logger.rb:20:in `block in call'

谢谢!

【问题讨论】:

  • 您有一个公共用户开始输入并因此触发 AJAX 请求,但您不希望同一个公共用户直接执行该 AJAX 请求?还是我误会了?
  • javascript 将在生成建议时调用路由,但用户自己应该永远无法访问端点/search/suggestions
  • 如何区分浏览器通过 JavaScript 调用和用户通过浏览器控制台执行相同操作?我不认为你可以。
  • 你是怎么解决这个问题的?我有同样的场景,使用 twitter typeahead 并且不希望人们访问预取 json
  • @user4584963 - 在我的ApplicationController 中,我有一个名为ajax_request? 的方法,它本质上是(defined? request) && request.xhr?。它正在检查请求是否是异步启动的。在我的操作中,我只是抛出一个错误unless ajax_request?。这应该会阻止用户在浏览器中四处浏览的大多数活动。但这并不是万无一失的,因为如果聪明的用户知道自己在做什么,他们总是可以异步发送他们的请求。它的目的是阻止大多数人,而不是密不透风。编辑:显然只有当您的 JS 通过 ajax 获取 URL 时才有效

标签: javascript jquery ruby-on-rails routes


【解决方案1】:

使用浏览器,任何人都可以在 url 中输入任何内容。那么如何阻止某人访问他们无权访问的 url/route/page?

您必须在控制器执行操作之前挂钩请求。如果对控制器的请求来自有效的请求者,则执行操作,否则显示消息并重定向,或任何您需要的。

我有一个应用程序,用户只能看到他们自己的供稿,而不能看到其他任何人;只编辑自己的帖子等。用户状态由会话控制器维护。

你的 twitter typeahead 请求者需要一些东西来识别自己,一个可以被验证进入控制器的状态。这可以通过多种方式实现。我不会试图猜测您的应用是如何设置的。

在控制器中使用 before_action 来测试有效的请求者,在你的例子中是你的 twitter typeahead:

class YourController < ApplicationController 
before_action :validate_access 

private 
  def validate_access 
      unless twitter_user? 
          flash[:danger] = "You do not have access to this feature." 
      redirect_to root_url (whatever redirect you need) 
      end 
  end

Catchall 301 重定向——安全网

在路由中,我总是喜欢有一个包罗万象的重定向,以防有人在浏览器中输入了无效的 URL。如果你没有这个并且有人手动编辑了一个在你的路由中不存在的 URL,你的应用程序会因找不到路由而崩溃,这很难看:

routes.rb

  # This is a catchall 301 redirect to home (does not help with (e) type errors)
  get "*path", to: redirect('/')

可能还有其他解决方案,但如果它对您有用,请尝试这个想法。如果您有任何问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2021-08-16
    • 2021-02-05
    相关资源
    最近更新 更多