-
-
Save jwo/1255275 to your computer and use it in GitHub Desktop.
class Api::RegistrationsController < Api::BaseController | |
respond_to :json | |
def create | |
user = User.new(params[:user]) | |
if user.save | |
render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email), :status=>201 | |
return | |
else | |
warden.custom_failure! | |
render :json=> user.errors, :status=>422 | |
end | |
end | |
end |
class Api::SessionsController < Api::BaseController | |
prepend_before_filter :require_no_authentication, :only => [:create ] | |
include Devise::Controllers::InternalHelpers | |
before_filter :ensure_params_exist | |
respond_to :json | |
def create | |
build_resource | |
resource = User.find_for_database_authentication(:login=>params[:user_login][:login]) | |
return invalid_login_attempt unless resource | |
if resource.valid_password?(params[:user_login][:password]) | |
sign_in("user", resource) | |
render :json=> {:success=>true, :auth_token=>resource.authentication_token, :login=>resource.login, :email=>resource.email} | |
return | |
end | |
invalid_login_attempt | |
end | |
def destroy | |
sign_out(resource_name) | |
end | |
protected | |
def ensure_params_exist | |
return unless params[:user_login].blank? | |
render :json=>{:success=>false, :message=>"missing user_login parameter"}, :status=>422 | |
end | |
def invalid_login_attempt | |
warden.custom_failure! | |
render :json=> {:success=>false, :message=>"Error with your login or password"}, :status=>401 | |
end | |
end |
@jwo Have you got an example of routes.rb when using a :api namespace with a devise_for :users together with the normal devise_for :users?
Got the same problem as mentioned here: https://groups.google.com/group/plataformatec-devise/browse_thread/thread/d2f4776e5109c0b3?pli=1#
Wondering if you solved this or could point me in the right direction.
@drblok -- I wouldn't have 2 devise_for... You can have separate resources :users
, but I don't see the need for multiple registration paths.
@drblok -- actually, sorry, that's incorrect... here's a setup for multiple devise paths. This works for me:
devise_for :chefs, :path => '', :path_names => { :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
namespace "api/v1", :as=>:api do
devise_for :chefs
resources :recipes, :only=>[:index, :show]
end
resources :chefs, :only=>[:show,:edit, :update, :delete] do
resource :avatar, :only=>[:show, :new, :create]
end
@jwo Thanks, I'll check it out and post my findings.
@jwo - I decided to remove the devise_for from my :api namespace and write my own as it's nothing more than rendering a JSON message if authentication fails. Thanks anyway for giving me stuff to think about to come to this conclusion ;)
Thanks for the response Dennis! I ended up using a lot of your registrations controller but I did remove the user.as_json in order to be able to return the token.
render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email), :status=>201
to
render :json=> { :token=>user.authentication_token, :email=>user.email }, :status=>201
@drblok Errr...Well I feel like an idiot... I completely misread the flow of conversation. Thanks for offering up the help anyway!
np!
Sorry to bring this back out from the dead, but doesn't before_filter :ensure_params_exist mean the app would also try to ensure parameters exist on destroy i.e. sign out ?
Does this work with active_for_authentication? (see http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Authenticatable)
@hackfanatic yes. The line should be before_filter :ensure_params_exist, only: :create
I made some changes to the latest version of @Bomadeno.
What are the names of the helpers devise generates you? After adding namespaces i am forced to change my helpers.
namespace :api do
namespace :v1 do
devise_for :users
end
end
Now i can access them like this current_api_v1_user or authenticate_api_v1_user!. Is there any way to maintain namespaces and access helper with just the name of the model?
thanks
I agree with @bilby91 that 2 namespaces are making the current_user quite ugly. What's the best practice to avoid this?
Hi there, I'm trying to make a API for a iOS app that will upload some videos to AWS s3. This is a great gist but, with the controllers are not extending from Devise::SessionsController and Devise::RegistrationsController?
Try another method, taken from my Spree Application
user = Spree::User.find_by(:email => params[:email])
unless user.nil?
if user.valid_password? params[:password]
render :json => '{"api_key": "#{user.spree_api_key}"}'
end
end
render :json => '{"error": "invalid email and password combination"}'
The point is that you can use valid_password? in devise for your convenient
Thanks minhtriet, this is useful and simpler. Do you have the RegistrationsController gist?
Is there a reason not to use warden.authenticate
instead of reinventing the wheel with your own finder and password-validation logic?
getting error
"undefined local variable or method `build_resource' for #Api::SessionsController:0x00000003f885b0"
i'm using devise 3.4.1 in rails 4.1.5, I have removed line 'include Devise::Controllers::InternalHelpers' and extended 'Api::SessionsController' < DeviseController, also I have not included the related file Api::RegistrationsController in my api does it affect ?
so what's the exact cause please clarify.
I'd suggest taking a look at https://github.com/gonzalo-bulnes/simple_token_authentication and/or https://github.com/thoulike/rails-api-authentication-token-example.
Dear,
It's nice post.
But I have one question.
How about if I setting for Devise with maximum_attempts = 5 and lock_strategy = :failed_attempts
Does it work like normal web base.
Currently I'm using device for connect to API,
It's really helpful to get answers.
Thanks a lot.
I get this error in rails
TypeError in Devise::ConfirmationsController#show
nil is not a symbol nor a string
Extracted source (around line #188):
186
187
188
189
190
191
# Handles <tt>*_was</tt> for +method_missing+.
def attribute_was(attr) # :nodoc:
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end
# Handles <tt>*_previously_changed?</tt> for +method_missing+.
namespace :api do
namespace :v1 do
devise_for :users, defaults: { format: :json }, as: :users
end
end
new_users_user_session GET /api/v1/users/sign_in(.:format) api/v1/sessions#new {:format=>:json}
users_user_session POST /api/v1/users/sign_in(.:format) api/v1/sessions#create {:format=>:json}
Good example but confused about where you set token?
In this way failed_attempts, doesn't work.
@Avatarr in this instance, the tokens are probably set or generated by Devise. This was removed from Devise after 3 for security reasons, though you can use a basic implementation like this one to get the functionality back
I forked this to work with latest devise: https://gist.github.com/2662058
InternalHelpers file is renamed, and made some other changes that now pass my tests