Skip to main content
Correct answer since Ruby 2.5's SecureRandom is safe!
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
  1. Generate your token using SecureRandom.hex. Or use the gem sysrandom.

    Apparently SecureRandom is not that secure. Still, there's a trade-off here: pick something from standard lib or pick a little known gem maintained by someone. For a well-informed decision I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  2. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.

    Generate your token with:

For an explanation on why this is necessary, I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  1. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.
  1. Generate your token using SecureRandom.hex. Or use the gem sysrandom.

    Apparently SecureRandom is not that secure. Still, there's a trade-off here: pick something from standard lib or pick a little known gem maintained by someone. For a well-informed decision I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  2. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.

  1. Generate your token with:

For an explanation on why this is necessary, I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  1. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.
Add note concerning ActiveSupport::SecurityUtils.secure_compare
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
  1. Generate your token using SecureRandom.hex. Or use the gem sysrandom.

    Apparently SecureRandom is not that secure. Still, there's a trade-off here: pick something from standard lib or pick a little known gem maintained by someone. For a well-informed decision I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  2. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.

  1. Generate your token using SecureRandom.hex. Or use the gem sysrandom.

    Apparently SecureRandom is not that secure. Still, there's a trade-off here: pick something from standard lib or pick a little known gem maintained by someone. For a well-informed decision I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  2. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token].

  1. Generate your token using SecureRandom.hex. Or use the gem sysrandom.

    Apparently SecureRandom is not that secure. Still, there's a trade-off here: pick something from standard lib or pick a little known gem maintained by someone. For a well-informed decision I suggest reading the sysrandom's README and the blog post How to Generate Secure Random Numbers in Various Programming Languages.

  2. Find the user record using the user's ID, email or some other attribute. Then, compare that user's token with the request's token with Devise.secure_compare(user.auth_token, params[:auth_token]. If you are on Rails 4.2.1+ you can also use ActiveSupport::SecurityUtils.secure_compare.

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot
  1. There should be some kind of mechanism that causes the token to expire. When implementing this mechanism take into account the trade-off between UX and security.

    Google expires a token if it has not been used for six months.

    Facebook expires a token if it has not been used for two months:

    Native mobile apps using Facebook's SDKs will get long-lived access tokens, good for about 60 days. These tokens will be refreshed once per day when the person using your app makes a request to Facebook's servers. If no requests are made, the token will expire after about 60 days and the person will have to go through the login flow again to get a new token.

  2. Upgrade to Rails 4 to use its encrypted cookie store. If you can't, then encrypt the cookie store yourself, like suggested herehere. There would absolutely be no problem in storing an authentication token in an encrypted cookie store.

  1. There should be some kind of mechanism that causes the token to expire. When implementing this mechanism take into account the trade-off between UX and security.

    Google expires a token if it has not been used for six months.

    Facebook expires a token if it has not been used for two months:

    Native mobile apps using Facebook's SDKs will get long-lived access tokens, good for about 60 days. These tokens will be refreshed once per day when the person using your app makes a request to Facebook's servers. If no requests are made, the token will expire after about 60 days and the person will have to go through the login flow again to get a new token.

  2. Upgrade to Rails 4 to use its encrypted cookie store. If you can't, then encrypt the cookie store yourself, like suggested here. There would absolutely be no problem in storing an authentication token in an encrypted cookie store.

  1. There should be some kind of mechanism that causes the token to expire. When implementing this mechanism take into account the trade-off between UX and security.

    Google expires a token if it has not been used for six months.

    Facebook expires a token if it has not been used for two months:

    Native mobile apps using Facebook's SDKs will get long-lived access tokens, good for about 60 days. These tokens will be refreshed once per day when the person using your app makes a request to Facebook's servers. If no requests are made, the token will expire after about 60 days and the person will have to go through the login flow again to get a new token.

  2. Upgrade to Rails 4 to use its encrypted cookie store. If you can't, then encrypt the cookie store yourself, like suggested here. There would absolutely be no problem in storing an authentication token in an encrypted cookie store.

added 13 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Improved answer - clarified a lot of sections and added even more links
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Bounty Awarded with 50 reputation awarded by Aaron Gray
Add link to GitHub session management and reword phrase
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Created link to SecureRandom stdlib and updated Devise link
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Removed recommendation to use a token only once. That mostly applies to systems with use-once refresh tokens like OAuth
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 121 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Added link to Devise's secure_compare method
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 582 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Added link to blog post about timing attacks
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 214 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 485 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 97 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 34 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Fixed link
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Bounty Awarded with 50 reputation awarded by Jeff Escalante
added 1268 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
added 473 characters in body
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading
Source Link
Ashitaka
  • 19.2k
  • 6
  • 58
  • 70
Loading