Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A SimpleTokenAuthentication-compatible JSON version of Devise::SessionsController. (UPDATE: For a discussion about this gist and a better version of it, please see https://github.com/gonzalo-bulnes/simple_token_authentication/issues/48#issuecomment-42133939)
# app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
# This controller provides a JSON version of the Devise::SessionsController and
# is compatible with the use of SimpleTokenAuthentication.
# See https://github.com/gonzalo-bulnes/simple_token_authentication/issues/27
def create
# Fetch params
email = params[:session][:email] if params[:session]
password = params[:session][:password] if params[:session]
id = User.find_by(email: email).try(:id) if email.presence
# Validations
if request.format != :json
render status: 406, json: { message: 'The request must be JSON.' }
return
end
if email.nil? or password.nil?
render status: 400, json: { message: 'The request MUST contain the user email and password.' }
return
end
# Authentication
user = User.find_by(email: email)
if user
if user.valid_password? password
user.reset_authentication_token!
# Note that the data which should be returned depends heavily of the API client needs.
render status: 200, json: { email: user.email, authentication_token: user.authentication_token, id: id }
else
render status: 401, json: { message: 'Invalid email or password.' }
end
else
render status: 401, json: { message: 'Invalid email or password.' }
end
end
def destroy
# Fetch params
user = User.find_by(authentication_token: params[:user_token])
if user.nil?
render status: 404, json: { message: 'Invalid token.' }
else
user.authentication_token = nil
user.save!
render status: 204, json: nil
end
end
end
@kzjeef

This comment has been minimized.

Show comment
Hide comment
@kzjeef

kzjeef Mar 15, 2014

Hi Gonzalo,

meet few issue when using this gist,

  1. I'm using devise 3.1, and the controler will call new function rather than create function
  2. also I got null of user.authentication_token. don't know what did I miss...

Thanks

kzjeef commented Mar 15, 2014

Hi Gonzalo,

meet few issue when using this gist,

  1. I'm using devise 3.1, and the controler will call new function rather than create function
  2. also I got null of user.authentication_token. don't know what did I miss...

Thanks

@kzjeef

This comment has been minimized.

Show comment
Hide comment
@kzjeef

kzjeef Mar 15, 2014

Update:

  1. for #1, yes, I need change to :create to :new to make it happen.
  2. 2 fixed by add the missing part in User.rb from this gist: https://gist.github.com/josevalim/fb706b1e933ef01e4fb6

  3. also add the reset auth token function to my user.rb model, paste it here for other reference:
    https://gist.github.com/kzjeef/9565261

kzjeef commented Mar 15, 2014

Update:

  1. for #1, yes, I need change to :create to :new to make it happen.
  2. 2 fixed by add the missing part in User.rb from this gist: https://gist.github.com/josevalim/fb706b1e933ef01e4fb6

  3. also add the reset auth token function to my user.rb model, paste it here for other reference:
    https://gist.github.com/kzjeef/9565261
@gonzalo-bulnes

This comment has been minimized.

Show comment
Hide comment
@gonzalo-bulnes

gonzalo-bulnes Mar 20, 2014

Hi @kzjeef!

For some reason I didn't receive any notification and I didn't notice yours comments until now.

  1. In fact naming the action :new or :create is merely a matter of taste. I prefer to keep the API actions as similar as possible to the "not only API" ones, and that's why I use to keep using :create and to drop :new. To me, :new displays the form and, from that point of view, is useless in an API context. YMMV.
  2. and 3. Your comments make me think you found this gist without knewing about the Simple Token Authentication gem. I wrote the gist as an example of JSON-enabled Devise::SessionsController to use with Simple Token Authentication.

The gem packages the content of the gist you quoted so you don't have to worry about that. If you didn't already, I think you should take a look at it ; )

In particular this question about JSON sessions controllers contains some context for this gist.

Regards!

Owner

gonzalo-bulnes commented Mar 20, 2014

Hi @kzjeef!

For some reason I didn't receive any notification and I didn't notice yours comments until now.

  1. In fact naming the action :new or :create is merely a matter of taste. I prefer to keep the API actions as similar as possible to the "not only API" ones, and that's why I use to keep using :create and to drop :new. To me, :new displays the form and, from that point of view, is useless in an API context. YMMV.
  2. and 3. Your comments make me think you found this gist without knewing about the Simple Token Authentication gem. I wrote the gist as an example of JSON-enabled Devise::SessionsController to use with Simple Token Authentication.

The gem packages the content of the gist you quoted so you don't have to worry about that. If you didn't already, I think you should take a look at it ; )

In particular this question about JSON sessions controllers contains some context for this gist.

Regards!

@dnlserrano

This comment has been minimized.

Show comment
Hide comment
@dnlserrano

dnlserrano Mar 23, 2014

Hi @gonzalo-bulnes

First of all, great work on the gem. Now the questions.

  1. I don't understand why you are using the session hash (i.e., cookies) in the create action. I'm creating a JSON API and thus the use of cookies does not seem to be the best option here.
  2. Isn't the destroy action "just another action which needs to authenticate the user"? In that sense, why do you overlook the user_email parameter in this case?

I was wondering how one could design a destroy action keeping the same ideas we are using to authenticate the user in any other action while following the DRY principles. A suggestion is to use the method for authentication in the other actions but this seems to be private to the ActsAsTokenAuthenticationHandlerMethods module.

Btw, my SessionsController is now looking like this.

Thanks in advance,
Daniel

dnlserrano commented Mar 23, 2014

Hi @gonzalo-bulnes

First of all, great work on the gem. Now the questions.

  1. I don't understand why you are using the session hash (i.e., cookies) in the create action. I'm creating a JSON API and thus the use of cookies does not seem to be the best option here.
  2. Isn't the destroy action "just another action which needs to authenticate the user"? In that sense, why do you overlook the user_email parameter in this case?

I was wondering how one could design a destroy action keeping the same ideas we are using to authenticate the user in any other action while following the DRY principles. A suggestion is to use the method for authentication in the other actions but this seems to be private to the ActsAsTokenAuthenticationHandlerMethods module.

Btw, my SessionsController is now looking like this.

Thanks in advance,
Daniel

@dnlserrano

This comment has been minimized.

Show comment
Hide comment
@dnlserrano

dnlserrano Mar 23, 2014

Hi again @gonzalo-bulnes.

After looking at this comment of yours a little more carefully, I think I got it. I now have basic custom SessionsController performing login (creation of auth_token) and logout (authenticating the user and destroying the auth_token in case authentatication was successful). Here is the new gist for it.

Would love to hear from you in regards to my previous questions anyway.

Regards!

dnlserrano commented Mar 23, 2014

Hi again @gonzalo-bulnes.

After looking at this comment of yours a little more carefully, I think I got it. I now have basic custom SessionsController performing login (creation of auth_token) and logout (authenticating the user and destroying the auth_token in case authentatication was successful). Here is the new gist for it.

Would love to hear from you in regards to my previous questions anyway.

Regards!

@gonzalo-bulnes

This comment has been minimized.

Show comment
Hide comment
@gonzalo-bulnes

gonzalo-bulnes Apr 2, 2014

Hi @dnlserrano, I believe you're right about both of your observations, this sessions controller needs a serious review.

I took a look to your gist; it looks better than mine. I'm aware of the Simple Token Authentication issue you opened (#48) about intenting to destroy the session with wrong credentials; once fixed, I think we could update your SessionsController and use it as a reference. Sadly I'm a bit short of time these days, but I'll be reading your updates.

Owner

gonzalo-bulnes commented Apr 2, 2014

Hi @dnlserrano, I believe you're right about both of your observations, this sessions controller needs a serious review.

I took a look to your gist; it looks better than mine. I'm aware of the Simple Token Authentication issue you opened (#48) about intenting to destroy the session with wrong credentials; once fixed, I think we could update your SessionsController and use it as a reference. Sadly I'm a bit short of time these days, but I'll be reading your updates.

@gonzalo-bulnes

This comment has been minimized.

Show comment
Hide comment
@gonzalo-bulnes

gonzalo-bulnes May 6, 2014

Update: @dnlserrano shared his RegistrationsController and SessionsController in that gist (original comment).

Owner

gonzalo-bulnes commented May 6, 2014

Update: @dnlserrano shared his RegistrationsController and SessionsController in that gist (original comment).

@elangolab

This comment has been minimized.

Show comment
Hide comment
@elangolab

elangolab Jun 12, 2014

Hi Gonzalo (@gonzalo-bulnes),

If we are doing all the ground work, there is nothing in Devise SessionController that is required, should this class still extend Devise SessionController.

elangolab commented Jun 12, 2014

Hi Gonzalo (@gonzalo-bulnes),

If we are doing all the ground work, there is nothing in Devise SessionController that is required, should this class still extend Devise SessionController.

@elangolab

This comment has been minimized.

Show comment
Hide comment
@elangolab

elangolab Jun 12, 2014

@gonzalo-bulnes , btw thanks for SimpleToken

elangolab commented Jun 12, 2014

@gonzalo-bulnes , btw thanks for SimpleToken

@a14m

This comment has been minimized.

Show comment
Hide comment
@a14m

a14m Jan 6, 2015

why is this code in the gist needed... can't you just check the current_user

PS I tried to check current user but it always return a user (whether i singed in with valid or invalid token) ?

a14m commented Jan 6, 2015

why is this code in the gist needed... can't you just check the current_user

PS I tried to check current user but it always return a user (whether i singed in with valid or invalid token) ?

@myrual

This comment has been minimized.

Show comment
Hide comment
@myrual

myrual Apr 26, 2017

I just write an article about how to add JSON API login based on Devise and simple token authentication. But I don't know how to test sign_out api with python code now. @gonzalo-bulnes

myrual commented Apr 26, 2017

I just write an article about how to add JSON API login based on Devise and simple token authentication. But I don't know how to test sign_out api with python code now. @gonzalo-bulnes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment