0

是否可以将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

4

1 回答 1

0

We were able to accomplish this with the following omniauth initializer (including configuration for google openid provider, though the same concept would probably apply to other providers):

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

This will utilize the site name in the callback, the original auth link, as well as the failure link. It can then be paired with the following routes in routes.rb:

get "/:site_name/auth/:provider/failure", :to => "my_omniauth#failure"
post "/:site_name/auth/:provider/callback", :to => "my_omniauth#callback"
于 2013-04-26T23:22:25.097 回答