OmniAuth不适用于Rails3中的Route Globbing

时间:2011-04-03 17:38:10

标签: ruby-on-rails ruby-on-rails-3 routes omniauth glob

我正在尝试按照Railscast 241 Simple OmniAuth进行操作,除非我在/config/routes.rb结尾处有路线全球覆盖,否则它会正常工作:

match '*uri' => "posts#index"

如果我使用globbing请求/auth/twitter,那么OmniAuth什么都不做:

Started GET "/auth/twitter" for 127.0.0.1 at 2011-04-03 19:17:44 +0200
  Processing by PostsController#index as HTML
  Parameters: {"uri"=>"auth/twitter"}
Rendered posts/index.html.haml within layouts/application (9.0ms)
Completed 200 OK in 103ms (Views: 14.6ms | ActiveRecord: 0.7ms)

没有通配路线,它可以正确验证。

有没有办法同时拥有路线通配和OmniAuth?

2 个答案:

答案 0 :(得分:17)

The OmniAuth process是在调用/auth/:provider网址时提供以下功能:

  1. 将请求传递给基础Rack / Rails应用程序,就像OmniAuth不在那里一样;
  2. 确定底层应用程序是否生成了404;
  3. 如果是,请调用实际的OmniAuth功能。
  4. 由于您基本上使用路由通配符匹配所有,因此您的应用程序永远不会提供404,而OmniAuth无法完成它的工作。我看到两个直接的选择。

    将OmniAuth路由与手动404匹配

    按如下方式添加新路线:

    match '/auth/:provider' => 'omniauth#passthru'
    

    然后创建一个生成404的控制器和动作:

    class OmniauthController < ApplicationController
      def passthru
        render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
      end
    end
    

    确定Glob路线中的404状态

    我假设您的glob路线将以某种方式搜索与URL匹配的帖子;你可以抓住失误(例如,当PostsController#index无法找到帖子时)并生成404。

    class PostsController < ApplicationController
      def index
        if @posts = Post.find_by_current_url_or_whatever
          render 'index'
        else
          render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
        end
      end
    end
    

答案 1 :(得分:0)

稍加修改suggestion of Brandon Tilley

# config/routes.rb
match '/auth/:provider/callback' => 'sessions#create'
match 'auth/*rest' => 'application#omniauth'
match '*uri' => 'posts#index'

# app/controllers/application_controller.rb
def omniauth
  render text: 'Authentication', status: 404
end