范围Omniauth路线

时间:2013-04-25 21:45:53

标签: ruby-on-rails-3 omniauth

是否可以将omniauth路径范围限定为资源?例如,假设我们有一个随意的网站建设网站,我可以通过以下方式在网站中查找网站:

get ":site_name", :to => "sites#show"

我现在想通过omniauth添加身份验证,但是它可以在每个站点上运行,所以如果我可以手动指定omniauth路由,它可能是:

get ":site_name/auth/:provider", :to => "omniauth#whatever"
get ":site_name/auth/failure", :to => "omniauth#failure"
get ":site_name/auth/:provider/callback", :to => "my_omniauth_callbacks#auth"

我们尝试过像这样使用path_prefix:

Rails.application.config.middleware.use OmniAuth::Builder do
  configure do |config|
    config.path_prefix = "/:site_name/auth"
  end

  # Providers
end

但这只是意味着我们必须访问/:site_name/auth/provider而不是能够使用/my_site_1/auth/provider

1 个答案:

答案 0 :(得分:0)

我们能够使用以下omniauth初始化程序(包括google openid提供程序的配置)完成此操作,但相同的概念可能适用于其他提供程序):

require "openid/store/filesystem"

Rails.application.config.middleware.use OmniAuth::Builder do
  AUTH_REGEX = /^\/([^\/]+)\/auth\/([^\/]+)$/
  CALLBACK_REGEX = /^\/([^\/]+)\/auth\/([^\/]+)\/callback$/
  SITE_REGEX = /^\/([^\/]+)(?:\/auth\/([^\/]+)\/callback)?/

  configure do |config|
    config.on_failure = lambda do |env|
      match_data = SITE_REGEX.match env["PATH_INFO"]

      if match_data
        provider = match_data[2] || "unknown"
        location = "/#{match_data[1]}/auth/#{provider}/failure"
      else
        location = "/unknown/auth/unknown/failure"
      end

      Rack::Response.new(["302 Moved"], 302, "Location" => location).finish
    end
  end

  callback_path = lambda do |env|
    env["PATH_INFO"] =~ CALLBACK_REGEX
  end

  request_path = lambda do |env|
    match_data = AUTH_REGEX.match env["PATH_INFO"]

    if match_data
      "/#{match_data[1]}/auth/#{match_data[2]}/callback"
    end
  end

  provider :openid, :name => "google",
                    :identifier => "https://www.google.com/accounts/o8/id",
                    :store => OpenID::Store::Filesystem.new("/tmp"),
                    :callback_path => callback_path,
                    :request_path => request_path
end

这将使用回调中的站点名称,原始auth链接以及失败链接。然后可以在routes.rb中配对以下路由:

get "/:site_name/auth/:provider/failure", :to => "my_omniauth#failure"
post "/:site_name/auth/:provider/callback", :to => "my_omniauth#callback"