User:Skunapa/sandbox

Devise is a rack based full-fledged authentication system for Rails. It is a complete MVC solution meaning it can support various models, views and controllers as part of its code and can be used be directly by developers. Devise is simple to use and starts up with a couple of commands but it is also highly customizable. Devise saves a lot of time and effort as many applications require user registration and authentication mechanisms which are difficult to develop from scratch.

Devise is similar to Restful Authentication or Authlogic which are also used for providing authentication in Rails applications. With Devise, developers can provide features like Login, Register and authenticate user information before showing them user-sensitive data.

History
Devise was first introduced in January 2010 by Plataformatec, a company which builds web and mobile applications. Devise is one of the few authentication systems which supports rack based applications and hence can support Rails (version 3 and higher) as they are completely rack based. The latest version of Devise available is v3.5.3 which is up to date with Rails 5 beta 2.

Warden
Devise gem is built on top of a rack application called Warden which is used to verify the identity of logged in user using a session string. In Warden, the id (which is the primary key of a user) is stored to match it later with the logged in user. Warden also provides restricted access to guest users depending on the functional requirements of an application. As Warden does not recognize a Rails application, it cannot provide any controllers, views, models, methods or configuration options. This is where Devise comes into play and can integrate with Rails seemlessly. A Strategy design pattern is used by Devise to interact with Warden for encrypting passwords, HTTP Authentication etc.

Getting Started
Although Devise is very useful and reduces the amount of effort in developing authentication mechanisms significantly, it requires a good understanding of the Rails framework. Hence it is advised for beginners to not use Devise. The following three commands will successfully install Devise: gem 'devise' bundle install rails generate devise:install After installing Devise one can run rails g devise . This will create a class with the model name given and also creates routes etc. The model will be configured with default Devise modules. The config/routes.rb file will be configured to point to the Devise controller corresponding to the model. rails generate devise user //Assuming that the model name is user If there are any configuration changes that are required like addition of new attributes we can add them to the migration file before migrating the model to the database. Also the modules in Devise that are to be used in the newly created model can be changed. Changes to these modules can be done in the corresponding model file that is created. For example, for the above model user, the corresponding file to edit would be models/user.rb. This is the place where additions can be done to relationship information of the model with other existing models in an application. After all required changes are made we can run rake db:migrate. Routes are configured in config/routes.rb file with a line like devise_for :users. Creation of Devise views is optional but can done so that options like Login and SignUp directly use the views generated by Devise. Devise has many views for generic options that come with authentication mechanisms so that the developer need not generate any new custom views. rails generate devise:views  can be used to create the corresponding views for the generated model. For example, the command for generating views for the user model given above would be: rails generate devise:views users These views are available under the users section and can be accessed by adding the corresponding view name in the URL. Examples of the URL for Login and SignUp actions of user are: http://0.0.0.0:3000/users/sign_up for Register and http://0.0.0.0:3000/users/sign_in for Login. Also when rake routes is run we can observe that many new routes are created. Each route will have a specific path in Rails and some of the paths that are associated with Devise are new_user_session_path, edit_user_registration_path, destroy_user_session_path etc.

Modules
There are 10 modules listed on the official page of Devise by Plataformatec. These modules are features that are contained in Devise and can be used by the developers depending on the use-cases or requirements of their application. Below is the list of modules: Information regarding each module is listed in README as well as the Plataformatec website. When devise generator is run using rails generate devise , a model class is created in app/models. This class can be used to specify many important configuration changes which vary from one application to another depending on the requirements. Perhaps the most important configurations that can be changed are the Devise modules which provide essential functionalities like enhanced security. The modules are included in an application in this way: class User < ActiveRecord::Base devise :database_authenticable, :omniauthable, :confirmable, :rememberable, :trackable, :timeoutable, :lockable end In addition to the classes generated Devise also generates a database migration in which fields related to the functionalities of these modules are added. Each field is related to a specific module and hence when a module is not required some of the fields may be removed from the migration to the database. Also most of these modules have specific forms and view associated with them. The forms are used by an end user to type in his/her information which will then be sent to the Devise controllers.
 * Database Authenticable
 * Omniauthable
 * Confirmable
 * Recoverable
 * Registerable
 * Rememberable
 * Trackable
 * Timeoutable
 * Validatable
 * Lockable

Methods
There are many classes in Devise which include models, controllers, helpers, views, routes etc. But there are some simple helper methods through which Devise exposes many of its features. Some important methods are given below: before_action :authenticate_user! If only some of the actions need authentication in a controller and some do not, we can use except clause so that only some actions are blocked as guest and others are accessible. The code with except clause is as below: before_action :authenticate_user! except [:index, :show] In the above example index and show are two controller actions associated with operations which do not require user authentication and can be browsed as a guest. An example class with authentication_user! is shown below: class EndUserBaseController < ApplicationController before_filter :authentication_user! end In this example the application will authenticate a user only if he is trying to perform an action associated with the EndUserBaseController. If before_filter is used in ApplicationController then it will be applied to all the controllers in the application. If in any of the above cases a user is not logged in the application backs off and redirects to its sign-in page. class BooksController < ApplicationController before_filter :authentication_user! def index @books = current_user.books.all end end Notice how authenticate_user! is used before checking the books checked out by the current user so as to ensure that the user is signed in before checking his/her history. <% if user_signed_in? %> <%- link_to "Logout", destroy_user_session_path, method :delete %> <% else %> <%- link_to "Sign Up", new_user_registration_path %> <%- link_to "Login", new_user_session_path %> <% end %> We need to use method :delete to logout so that Devise will only logout when a HTTP delete request is made by user and does not accidentally logout because of a malicious link that automatically logs out the user. The methods that are most frequently used by developers are current_user and user_signed_in? which are present as helper methods. Also if the methods are to be referred to an Admin then replace user in each method with admin i.e. current_user becomes current_admin etc.
 * authenticate_user! : This method is used to check whether a user is logged in before he/she attempts to perform a specific set of controller actions. authenticate_user! may be called with before_action as shown below to ensure the user is logged in before performing any of the operations.
 * current_user : current_user method is used to return the model class corresponding to the user who is currently signed in. For example, if you are building a library application, you may retrieve all the checked out books of a user as:
 * user_signed_in? : As the name suggests, user_signed_in? method is used to check whether a user is signed in. This is useful when you want to show two different pages depending on whether a user has logged in or not. For example, when a user is logged in you want to show him/her an option to Logout otherwise you want to show Register or Login options.
 * sign_in(@user) and sign_out(@user) : These methods are used to login(sign_in(@user)) or logout(sign_out(@user)) a newly created or existing user.
 * user_session : This method returns metadata about the user that is currently logged in.

Real-time Applications
Devise can be used in any application requiring an authentication mechanism to verify user information. A registered user can login and check information pertaining only him/her using Devise. Some of the real-time applications where Devise can be used for authentication are:
 * Library Management System: to show user his previous book check-out history.
 * Class Management Portal: to show students and instructors their registered courses.
 * Messaging applications: to check previous messages sent or received by a user.