I'm trying to add Authentication via json in my project using devise configuration :token_authenticatable.
I have the working sessions_controller#create code which was taken from this article - http://blog.codebykat.com/2012/07/23/remote-api-authentication-with-rails-3-using-activeresource-and-devise/
def create
build_resource
resource = User.find_for_database_authentication(:email => params[:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:password])
resource.ensure_authentication_token! #make sure the user has a token generated
render :json => { :authentication_token => resource.authentication_token, :user_id => resource.id }, :status => :created
return
end
end
def invalid_login_attempt
warden.custom_failure!
render :json => { :errors => ["Invalid email or password."] }, :success => false, :status => :unauthorized
end
The problem is that native devise sessions_controller#create looks like this
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
end
And i don't know how to combine this two create methods to have authentication working on website and via json too?
UPDATE
The working code
def create
respond_to do |format|
format.json do
build_resource
resource = User.find_for_database_authentication(:email => params[:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:password])
resource.ensure_authentication_token! #make sure the user has a token generated
render json: { authentication_token: resource.authentication_token, user_id: resource.id }, status: :created
return
end
end
format.html do
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
end
end
end
The token-based verification method works simply. The user enters his details and sends the request to the server. If the information is correct, the server creates a unique HMACSHA256 encoded token, also known as the JSON (JWT) web token.
You want your SessionsController#create
method to look something like this:
class Users::SessionsController < Devise::SessionsController
def create
resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#new")
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_to do |format|
format.html do
respond_with resource, location: redirect_location(resource_name, resource)
end
format.json do
render json: { response: 'ok', auth_token: current_user.authentication_token }.to_json, status: :ok
end
end
end
end
...and make sure you've configured devise to use the token authentication key your clients will pass along.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With