6

I have a rails api only application [config.api_only = true] in which I enable the cookies through these following lines:

in application.rb:

config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::Cookies
config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::Session::CookieStore

in application_controller.rb

include ActionController::Helpers
include ActionController::Cookies

I also added secret_token.rb as follows:

Rails.application.config.secret_token = 'token'

in my controller, I am trying to store the session like this:

def index
    #other codes
    session[:userid] = useridstring
    render :text => session[:userid]
end

Note: however, after executing this in chrome, I am examining the cookie and none is set...

then in the same controller, but in another action, I am trying to read the session like this:

def readsession
    userId = session[:userid]
    render :text => userId
end

and nothing is rendered.. :(

Is there anything I missed?

I tried following the answer here which suggest that I set config.api_only = false, however the result is the same (I have no cookie set, and when read in another controller, session is still empty

Sorry that it is such a basic question (or initial configuration matter), I am still very new in ruby and rails..

Community
  • 1
  • 1
Jenny Kim
  • 1,505
  • 2
  • 16
  • 25
  • 2
    Support your API is consumed by a mobo application, so how that application would store cookies? Of course, a browser can play with cookies, but a generic app, or a general consumer of your API may not be able to do so. So you better need to use tokens for authentication. – Arslan Ali Mar 03 '16 at 09:18
  • @BilalMaqsood: ohh.. yes it is for mobile! I haven't thought of that.. how do I use tokens for authentication instead? :O – Jenny Kim Mar 03 '16 at 10:15
  • @BilalMaqsood: cookie is indeed available in mobile, checkout CookieManager in Android, and NSUrlConnection also handles cookie automatically in iOS.. I'd like to know how you handle tokens though.. I know parse.com did this way too – Jenny Kim Mar 03 '16 at 10:38
  • 1
    I've given answer for authentication through token. Check it out. – Arslan Ali Mar 03 '16 at 10:39

1 Answers1

8

Since an API is always client independent, so it's best to use a token for authentication.

Here's how:

  1. Add a column called token in users table.
  2. A user comes and logs in.
  3. As he logs in, a token(a string of random characters) is generated, and saved in the database.
  4. The string is passed along as well, and any subsequent request will come with that token.
  5. Since each request comes with a token, you can check the token for its database existence, and association with the right user.
  6. As a user logs out, delete the token from the database.
Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
  • thanks for the explanation! Do you have extra resources regarding this? I'm currently googling and is quite confused about database backed cookies vs token for authentication (which is stored in db as well).. they are quite similar concept (you send back some token id) but might be different, lol – Jenny Kim Mar 03 '16 at 10:40
  • 1
    A few months ago, I built an API, and I built all the authentication functionality from scratch. It's not that difficult. And for your case, if you get back a different token id, simply say the user: 'You must be signed in to access this application.' With only a valid token, you can assume that a user is signed in. – Arslan Ali Mar 03 '16 at 10:49
  • @HakimHauston if my answer helped you, you can accept it. – Arslan Ali Mar 08 '16 at 10:45
  • I think this is quite bad approach. First you have to store it on FE side as well (localStorage, cookie etc) which is double work. Then how you're handling token expiration and token refreshing? Also, when you delete it from the Db it has to be deleted on FE as well so double work again. For me the best approaches would be Oauth2 authentication or cookie session with httpOnly flag set to true. – zauzaj Dec 02 '20 at 17:58