Tiddle provides Devise strategy for token authentication in API-only Ruby on Rails applications. Its main feature is support for multiple tokens per user.
Tiddle is lightweight and non-configurable. It does what it has to do and leaves some manual implementation to you.
Add this line to your application's Gemfile:
gem'tiddle'And then execute:
$ bundle
- Add
:token_authenticatableinside your Devise-enabled model:
classUser < ActiveRecord::Basedevise:database_authenticatable,:registerable,:recoverable,:trackable,:validatable,:token_authenticatableend- Generate the model which stores authentication tokens. The model name is not important, but the Devise-enabled model should have association called
authentication_tokens.
rails g model AuthenticationToken body:string:index user:references last_used_at:datetime expires_in:integer ip_address:string user_agent:string
classUser < ActiveRecord::Basehas_many:authentication_tokensendbody, last_used_at, ip_address and user_agent fields are required.
- Customize
Devise::SessionsController. You need to create and return token in#createand expire the token in#destroy.
classUsers::SessionsController < Devise::SessionsControllerdefcreateuser=warden.authenticate!(auth_options)token=Tiddle.create_and_return_token(user,request)renderjson: {authentication_token: token}enddefdestroyTiddle.expire_token(current_user,request)ifcurrent_userrenderjson: {}endprivate# this is invoked before destroy and we have to override itdefverify_signed_out_userendend- Require authentication for some controller:
classPostsController < ApplicationControllerbefore_action:authenticate_user!defindexrenderjson: Post.allendend- Send
X-USER-EMAILandX-USER-TOKENas headers of every request which requires authentication.
You can read more in a blog post dedicated to Tiddle - https://blog.sundaycoding.com/blog/2015/04/04/token-authentication-with-tiddle/
The safest solution in API-only application is not to rely on Rails session at all and disable it. Put this line in your application.rb:
config.middleware.deleteActionDispatch::Session::CookieStoreMore: https://blog.sundaycoding.com/blog/2015/04/04/token-authentication-with-tiddle/#rails-session
Change config.authentication_keys in Devise intitializer and Tiddle will use this value.
Usually it makes sense to remove user's tokens after a password change. Depending on the project and on your taste, this can be done using various methods like running user.authentication_tokens.destroy_all after the password change or with an after_save callback in your model which runs authentication_tokens.destroy_all if encrypted_password_changed?.
In case of a security breach, remove all existing tokens.
Tokens are expiring after certain period of inactivity. This behavior is optional. If you want your token to expire, create it passing expires_in option:
token=Tiddle.create_and_return_token(user,request,expires_in: 1.month)