User Authentication into Devise from iOS - ios

I am creating an application where user is going to sign in with username and password. At the back end and also for the website I am using ruby on rails where the authentication is handled by Devise. With the last edition of Devise they have depriciated the Authentication Token. I am lost in terms of how to authenticate from iOS ? Any suggestions ? How am I going to modify the gem files etc.

See this gist from Jose Valim Safe or Unsafe Tokens
Basically you will want to write your own auth token methods. You need to generate tokens and later compare them. You should read all of the comments, the discussion is pretty good.

Related

Devise + Patreon OAuth in Ruby on Rails

I have implemented the devise+patreon gem in my Rails application without issues. Now, devise requires an email/password by default when creating a User, but Patreon just uses the oauth integration.
I am wondering, what is the proper strategy to use so that I can migrate the Patreon Oauth users as Devise users, without having to set dummy passwords/emails to allow for validation to go through. I still want to eventually allow users to register via Devise natively, as well as through Patreon.
Is there maybe a known strategy/gem/addition for devise that I may have missed that can easily achieve that?
You can retrieve the user email and a lot of other infos (see here) about the user in the login call to patreon's services, but password will remain unknown, you can't just copy & paste a User.

JSON Web Token with Devise

I hope this does not count as an opinionated question. I just need to be pointed in the right direction.
I am modifying the Devise gem to work purely with JSON. I have had no problems with the registration, confirmation, re-confirmation, locking so far.
However, while working with the sign in, I dug deeper and understand that the default Devise sign in strategy uses Warden as it has to do with sessions and Rack authentication.
I understand JWT contains all the information in itself and does not need sessions.
So if I strip the default Devise strategy of everything and simply return a JWT on success and errors on error, would that be the right approach?
Am I missing something?
In order to use JWT with devise, I recommend to not monkey patch devise and instead use a tool others can audit and test.
For this reason, I developed devise-jwt. It does zero monkey patching and leverages warden, which is the authentication library below devise. You can also read more about it in this post I wrote: A Secure JWT Authentication Implementation for Rack and Rails
Hope it helps
I wouldn't use devise_token_auth since it seems like too much hassle and ... you store tokens in db :/. Why would we want to do so if JWT is available.
I'd rather add a new strategy to Warden/Devise couple and let them work as they should.
Here's an example: https://medium.com/#goncalvesjoao/rails-devise-jwt-and-the-forgotten-warden-67cfcf8a0b73 . One thing to note: JWTWrapper doesn't really belong to app/helpers/ . You need to inject somewhere a call to JWTWrapper.encode({ user_id: current_user.id }) once your users successfully signs in with their email/password. Perhaps in the Devise SessionsController?
def create
self.resource = warden.authenticate!(auth_options)
sign_in(resource_name, resource)
yield resource if block_given?
render json: JWTWrapper.encode({user_id:current_user.id})
end
You might want to do this only for xhr or json (format) requests
You probably shouldn't be hacking your Devise gem source. I suggest to just use Devise Token Auth gem to handle tokens instead.
https://github.com/lynndylanhurley/devise_token_auth
It will generate and authenticate valid RFC 6750 Bearer Tokens.
According to their README.
Seamless integration with both the the venerable ng-token-auth module for angular.js and the outstanding jToker plugin for jQuery.
Oauth2 authentication using OmniAuth.
Email authentication using Devise, including:
User registration
Password reset
Account updates
Account deletion
Support for multiple user models.
It is secure.
Sorry for late answer, but I'm actually working on the same problem, and want to share my opinions on that.
First, I would emphasize not changing Davise sources, this will likely bring you to further problems, especially when Devise code changes.
On the other hand, as I have encountered devise-token-auth, it might not be viable for your needs, especially in distributed systems (SOA). Perhaps I'm wrong, but as I see devise-token-auth, you can't add Subjects to restrict user access solely on the token. If you don't need this feature, you really should try devise-token-auth.
If you want to store additional information in the token, you could try to authenticate against a regular devise or devise-token-auth and then encode your information using a JWT gem.
Example can be found here: https://www.sitepoint.com/introduction-to-using-jwt-in-rails/

Is devise's token_authenticatable secure?

I'm building a simple api with Rails API, and want to make sure I'm on the right track here. I'm using devise to handle logins, and decided to go with Devise's token_authenticatable option, which generates an API key that you need to send with each request.
I'm pairing the API with a backbone/marionette front end and am generally wondering how I should handle sessions. My first thought was to just store the api key in local storage or a cookie, and retrieve it on page load, but something about storing the api key that way bothered me from a security standpoint. Wouldn't be be easy to grab the api key either by looking in local storage/the cookie or sniffing any request that goes through, and use it to impersonate that user indefinitely? I currently am resetting the api key each login, but even that seems frequent - any time you log in on any device, that means you'd be logged out on every other one, which is kind of a pain. If I could drop this reset I feel like it would improve from a usability standpoint.
I may be totally wrong here (and hope I am), can anyone explain whether authenticating this way is reliably secure, and if not what a good alternative would be? Overall, I'm looking for a way I can securely keep users 'signed in' to API access without frequently forcing re-auth.
token_authenticatable is vulnerable to timing attacks, which are very well explained in this blog post. These attacks were the reason token_authenticatable was removed from Devise 3.1. See the plataformatec blog post for more info.
To have the most secure token authentication mechanism, the token:
Must be sent via HTTPS.
Must be random, of cryptographic strength.
Must be securely compared.
Must not be stored directly in the database. Only a hash of the token can be stored there. (Remember, token = password. We don't store passwords in plain text in the db, right?)
Should expire according to some logic.
If you forego some of these points in favour of usability you'll end up with a mechanism that is not as secure as it could be. It's as simple as that. You should be safe enough if you satisfy the first three requirements and restrict access to your database though.
Expanding and explaining my answer:
Use HTTPS. This is definitely the most important point because it deals with sniffers.
If you don't use HTTPS, then a lot can go wrong. For example:
To securely transmit the user's credentials (username/email/password), you would have to use digest authentication but that just doesn't cut it these days since salted hashes can be brute forced.
In Rails 3, cookies are only shrouded by Base64 encoding, so they can be fairly easily revealed. See Decoding Rails Session Cookies for more info.
Since Rails 4 though, the cookie store is encrypted so data is both digitally verified and unreadable to an attacker. Cookies should be secure as long as your secret_key_base is not leaked.
Generate your token with:
SecureRandom.hex only if you are on Ruby 2.5+.
The gem sysrandom if you are on an older Ruby.
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.
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.
Do not find the user record with a Rails finder like User.find_by(auth_token: params[:auth_token]). This is vulnerable to timing attacks!
If you are going to have several applications/sessions at the same time per user, then you have two options:
Store the unencrypted token in the database so it can be shared among devices. This is a bad practice, but I guess you can do it in the name of UX (and if you trust your employees with DB access).
Store as many encrypted tokens per user as you want to allow current sessions. So if you want to allow 2 sessions on 2 different devices, keep 2 distinct token hashes in the database. This option is a little less straightforward to implement but it's definitely safer. It also has the upside of allowing you to provide your users the option to end current active sessions in specific devices by revoking their tokens (just like GitHub and Facebook do).
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.
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.
You should also have a contingency plan, for example, a rake task to reset a subset of tokens or every single token in the database.
To get you started, you could check out this gist (by one of the authors of Devise) on how to implement token authentication with Devise. Finally, the Railscast on securing an API should be helpful.
You can try to use rails4 with your API, it's providing more security and use devise 3.1.0rc
In Rails 4.0, several features have been extracted into gems.
ActiveRecord::SessionStore
Action Caching
Page Caching
Russian Doll-caching through key-based expiration with automatic dependency management of nested templates.
http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies
Devise 3.1.0.rc runs on both Rails 3.2 and Rails 4.0.
http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/
Devise is deprecation of TokenAuthenticatable in 3.1.0rc but you can build your own TokenAuthenticatable method for security issue. It's more reliable and secure.
For token, session store you can go through http://ruby.railstutorial.org/chapters/sign-in-sign-out and http://blog.bigbinary.com/2013/03/19/cookies-on-rails.html for more understable.
At last you should go through these kind of encryption and decryption "Unable to decrypt stored encrypted data" to get the more security.

session management in rails without User model

I have an rails app which relies on authenticating username/password entered to an external webservice. Rails app will not have a user model. When a user enters login/password and it makes a post request to check that login/password. External application will return back a cookie or token which can be used for subsequent requests made from rails app.
There is no User model in the rails app since all the users are stored in an external application.
Is there a gem which let me strictly do session management? I'm planning on storing that token in a session.
why not just create a sessions controller that saves the token into a session? I don't see a need for a gem.
something like
sessions[:token] = token
If you are dealing with a tokens that expire like facebook you can take a look at this
http://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens/
hope it helps
I might look at the way Michael Hartl does user sessions in his Rails tutorial. What you want is something slightly different, but you might be able to reuse some of what he did there. http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec-current_user
(It's also just a good tutorial to go through, regardless of your level of Rails experience.)

User membership pattern rails [duplicate]

This question already has answers here:
Closed 10 years ago.
In the .Net world we have the Membership provider, with this we can fully automate user registration and management. Does such a gem exist for the Ruby on Rails community.
I am looking for something that would allow a user to register, retrieve lost password, modify password and login.
See the answers given to this question recently - again, I would highly recommend Devise and the two railscasts on it, http://railscasts.com/episodes/209-introducing-devise and http://railscasts.com/episodes/210-customizing-devise. Devise handles all the things you described above - from the GitHub page:
"Confirmable: sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
Recoverable: resets the user password and sends reset instructions.
Registerable: handles signing up users through a registration process, also allowing them to edit and destroy their account."
Hope that helps!
Take a look at Devise - http://github.com/plataformatec/devise
It's a popular Rails engine for user authentication and should do what you need (and more).
Not sure that it has all of the features you want, but I really like restful-authentication.
http://agilewebdevelopment.com/plugins/restful_authentication
Features per website:
Login / logout
Secure password handling
Account activation by validating email
Account approval / disabling by admin
Rudimentary hooks for authorization and access control.
It also makes an appearance in a screen cast over at http://www.buildingwebapps.com/learningrails
Episode 11 about adding User Authentication. Watch the others if you are 100% new to rails, but if you just want to see them use the gem, skip to that one.
Check railscasts for a number of new options, including OmniAuth, Sorcery (my choice this week), and authentication from scratch, which may be less painful than the options listed before.

Resources