扩展Devise SessionsController以使用JSON进行身份validation

我正在尝试为iphone应用程序构build一个rails API。 devise工作正常login通过Web界面,但我需要能够创build和销毁会议使用REST API,我想使用JSON,而不是必须在会议控制器上进行POST,必须parsingHTML和处理redirect。

我以为我可以做这样的事情:

class Api::V1::SessionsController < Devise::SessionsController def create super end def destroy super end end 

和在config / routes.rb我补充说:

 namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end 

耙路由显示路由设置正确:

  api_v1_sessions POST /api/v1/sessions(.:format) {:action=>"create", :controller=>"api/v1/sessions"} api_v1_session DELETE /api/v1/sessions/:id(.:format) {:action=>"destroy", :controller=>"api/v1/sessions"} 

当我POST /用户/会议一切正常。 我得到一些HTML和302。

现在,如果我POST / api / v1 /会话,我得到:

未知的操作AbstractController :: ActionNotFound

 curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST http://localhost:3000/api/v1/sessions -d "{'user' : { 'login' : 'test', 'password' : 'foobar'}}" 

这是最后的工作。

 class Api::V1::SessionsController < Devise::SessionsController def create respond_to do |format| format.html { super } format.json { warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new") render :status => 200, :json => { :error => "Success" } } end end def destroy super end end 

还要改变routes.rb,记住顺序很重要。

 devise_for :users, :controllers => { :sessions => "api/v1/sessions" } devise_scope :user do namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end end resources :users 

我结束了@ akshay的答案和@ mm2001的答案。

 class Api::SessionsController < Devise::SessionsController def create warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure") render :json => {:success => true} end def destroy Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name) render :json => {} end def failure render :json => {:success => false, :errors => ["Login Failed"]} end end 

…和devise初始值设定项中,我必须这样做,以获得#create方法使用我的:recall处理程序

 # config/initializers/devise.rb config.navigational_formats = [:"*/*", "*/*", :html, :json] 

这是与Devise 1.5.1和Rails 3.1。

最近的答案在这里: http : //jessehowarth.com/devise有更多的细节(每使用Devise 1.3来validationJSONlogin请求 )

我通过创build一个分配身份validation令牌的小型服务来解决这个问题。 我写了一篇关于它的博客文章: http : //matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/ 。 你也可以在这里获取代码: https : //github.com/matteomelani/Auth-Token-Service-Prototype 。

从devise的#devise_scope的rdoc:

设置控制器中使用的devise范围。 如果你有自定义的路由,你需要调用这个方法(别名as:as)来指定它的目标是哪个控制器。

 as :user do get "sign_in", :to => "devise/sessions#new" end 

请注意,您不能将两个范围映射到相同的URL。 请记住,如果您尝试访问设备控制器而未指定范围,则会引发ActionNotFound错误。

看起来你需要把它包装在#as块中:

 as :user do namespace :api do namespace :v1 do resources :sessions, :only => [:create, :destroy] end end end 

创build/销毁会话的另一种解决scheme是使用Devise的token_authenticatable模块,然后更新API中的其他函数,以便将令牌作为必需参数。 这可以说是一个更复杂的devise,因为它保留了无状态(即没有会话状态)。 当然,这个build议适用于你的JSON API,但我不会推荐你的HTML UI(浏览器的URL栏中的长符号string不是很好看)。

看这里的例子。

不确定导航格式应该使用,一个API是不是真的…

通过这个博客文章只是添加

 respond_to :html, :json 

到你的控制器。