7

我正在尝试遵循 Railscast 241 Simple OmniAuth 并且它工作正常,除非我在末尾有 Route Globbing /config/routes.rb

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

如果我/auth/twitter使用 globbing 请求,那么 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)

如果没有 globbing 路由,它会正确地进行身份验证。

有没有办法同时拥有路由 globbing 和 OmniAuth?

4

2 回答 2

17

OmniAuth 过程/auth/:provider是在调用 URL时提供以下功能:

  1. 将请求传递给底层的 Rack/Rails 应用程序,就好像 OmniAuth 不存在一样;
  2. 判断底层应用是否产生404;
  3. 如果是,请调用实际的 OmniAuth 功能。

由于您本质上是使用路由通配符匹配所有内容,因此您的应用程序永远不会给出 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
于 2011-04-04T02:23:56.653 回答
0

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
于 2011-04-04T08:28:07.417 回答