with scotch rails only based ruby-on-rails ruby authentication devise

ruby on rails - scotch - Extender Devise SessionsController para autenticarse con JSON



scotch rails api only (7)

Estoy tratando de construir una API de rieles para una aplicación de iPhone. Devise funciona bien para los inicios de sesión a través de la interfaz web, pero necesito poder crear y destruir sesiones usando REST API y quiero usar JSON en lugar de tener que hacer un POST en el controlador de sesiones y tener que analizar el HTML y manejar un redirigir

Pensé que podría hacer algo como esto:

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

y en config / routes.rb agregué:

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

las rutas de rake muestran que las rutas están configuradas correctamente:

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"}

Cuando PUBLICO a / usuario / sesiones todo funciona bien. Obtengo algo de HTML y un 302.

Ahora si PUBLICO a / api / v1 / sessions, obtengo:

Acción desconocida 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''}}"


Del rdoc para el #devise_scope del dispositivo:

Establece el alcance del dispositivo que se utilizará en el controlador. Si tiene rutas personalizadas, debe llamar a este método (también con alias como: as) para especificar a qué controlador está dirigido.

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

Tenga en cuenta que no puede tener dos ámbitos asignados a la misma URL. Y recuerde, si intenta acceder a un controlador de diseño sin especificar un alcance, se generará un error de ActionNotFound.

Parece que debes envolverlo en un bloque #as:

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


Esto es lo que finalmente funcionó.

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

También cambie routes.rb, recuerde que el orden es importante.

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


No estoy seguro de que se utilicen formatos de navegación, una API no es realmente eso ...

Por esta publicación de blog simplemente agrega

respond_to :html, :json

a tus controladores.



Terminé usando una combinación de la respuesta de @ akshay y la respuesta de @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

... y en el inicializador del dispositivo, tuve que hacer esto para obtener el método #create para usar mi controlador :recall

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

Esto es con el Devise 1.5.1 y Rails 3.1.



Una solución alternativa para crear / destruir sesiones es usar el módulo token_authenticatable de Devise, y luego actualizar las otras funciones en su API para que tomen el token como un parámetro obligatorio. Este es posiblemente un diseño más ReSTful, ya que conserva la apatridia (es decir, no hay ningún estado de sesión en ninguna parte). Por supuesto, este consejo es válido para su API JSON, pero no recomendaría lo mismo para su interfaz de usuario HTML (las cadenas de token largas en la barra de URL de su navegador no son una buena idea).

Vea here para un ejemplo.