我正在研究基于Rails的API。我最近开始尝试对它进行版本化。 (我正在使用Versionist gem,以防万一。)一个版本('v2')使用Devise和Omniauth通过Facebook / Twitter验证用户。
我希望与此版本相关联的所有路由都具有相应的版本前缀(因此users/:username/foo
变为v2/users/:username/foo
等),但我已经发现放置devise_for
在api_version
块内阻止了Devise助手(current_user
,user_signed_in?
等)的工作,因此它继续存在于块外:
routes.rb中:
devise_for :user, :path => '', :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}, :skip => [:registrations, :confirmations, :sessions, :passwords]
api_version(:module => "V2", :path=>"v2") do
resources :authentications, :only => [:update, :destroy]
devise_scope :user do
post 'login' => 'sessions#create', :as => 'user_session'
get 'logout' => 'sessions#destroy'
post 'password' => 'devise/passwords#create'
put 'password' => 'devise/passwords#update'
end
end
一切看起来都很棒......除了Devise生成的omniauth路线:
rake路线输出:
user_omniauth_authorize /auth/:provider(.:format)
user_omniauth_callback /auth/:action/callback(.:format)
现在,一些google-fu透露,有一个设计配置设置,所以我将以下内容添加到我们的设计初始化器(config/initializers/devise.rb
)中:
Devise.setup do |config|
config.omniauth_path_prefix = 'v2/auth'
end
现在,rake路线产生看起来合理的路径:
user_omniauth_authorize /v2/auth/:provider(.:format) v2/users/omniauth_callbacks#passthru {:provider=>/(?!)/}
user_omniauth_callback /v2/auth/:action/callback(.:format) v2/users/omniauth_callbacks#(?-mix:(?!))
但是,当我尝试通过调用api.localhost/v2/auth/facebook
来访问此路由时,出现路由错误:
ActionController::RoutingError (No route matches [GET] "/v2/auth/facebook")
知道这里发生了什么吗?
答案 0 :(得分:1)
您缺少路线中的提供商名称,因此它们与facebook
中的/v2/auth/facebook
部分不匹配。正确的路线目的地应该类似于v2/users/omniauth_callbacks#(?-mix:facebook)
。
您是否在用户模型中指定了提供商?
devise_for ..., :omniauthable, :omniauth_providers => [:facebook]
为了记录,我正在使用Rails 3.2和Devise 3.0,并且改变的路线似乎有效(我还没有进一步看看是否会有其它东西会破坏)。