title: User Authentication with Grape and Devise
body: <p>I have difficulties to understand and also properly implement <strong><em>User Authentication</em></strong> in APIs. In other words, I have serious problem to understand the integration of Grape API with front-end frameworks such as Backbone.js, AngularJS or Ember.js. </p>
  
  <p>I'm trying to pivot all different approaches and read a lot about that, but Google returns me truly bad resources and it seems to me, like there is no really good article on this topic - <em>Rails and User authentication with Devise and front-end frameworks</em>.</p>
  
  <p>I will describe my current pivot and I hope you can provide me some feedback on my implementation and maybe point me to the right direction.</p>
  
  <p><strong>Current implementation</strong></p>
  
  <p>I have backend <strong>Rails REST API</strong> with following <strong><em>Gemfile</em></strong>(I will purposely shorten all file code)</p>
  
  <pre><code>gem 'rails', '4.1.6'
  gem 'mongoid', '~&gt; 4.0.0'
  gem 'devise'
  gem 'grape'
  gem 'rack-cors', :require =&gt; 'rack/cors'
  </code></pre>
  
  <p>My current implementation has only APIs with following Routes(<strong><em>routes.rb</em></strong>):</p>
  
  <pre><code>api_base      /api        API::Base
       GET        /:version/posts(.:format)
       GET        /:version/posts/:id(.:format)
       POST       /:version/posts(.:format)
       DELETE     /:version/posts/:id(.:format)
       POST       /:version/users/authenticate(.:format)
       POST       /:version/users/register(.:format)
       DELETE     /:version/users/logout(.:format)
  </code></pre>
  
  <p>I created have following model <strong><em>user.rb</em></strong></p>
  
  <pre><code>class User
    include Mongoid::Document
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable
  
    field :email,              type: String, default: ""
    field :encrypted_password, type: String, default: ""
  
    field :authentication_token,  type: String
  
    before_save :ensure_authentication_token!
  
    def ensure_authentication_token!
      self.authentication_token ||= generate_authentication_token
    end
  
    private
  
    def generate_authentication_token
      loop do
        token = Devise.friendly_token
        break token unless User.where(authentication_token: token).first
      end
    end   
  end
  </code></pre>
  
  <p>In my controllers I created following folder structure: <em>controllers->api->v1</em> and I have created following shared module Authentication (<strong><em>authentication.rb</em></strong>)</p>
  
  <pre><code>module API
    module V1
      module Authentication
        extend ActiveSupport::Concern
  
        included do
          before do
             error!("401 Unauthorized", 401) unless authenticated?
           end
  
           helpers do
             def warden
               env['warden']
             end
  
             def authenticated?
               return true if warden.authenticated?
               params[:access_token] &amp;&amp; @user = User.find_by(authentication_token: params[:access_token])
             end
  
             def current_user
               warden.user || @user
             end
           end
         end
       end
     end
  end
  </code></pre>
  
  <p>So every time when I want to ensure, that my resource will be called with Authentication Token, I can simply add this by calling: <code>include API::V1::Authentication</code> to the Grape resource:</p>
  
  <pre><code>module API
    module V1
      class Posts &lt; Grape::API
        include API::V1::Defaults
        include API::V1::Authentication
  </code></pre>
  
  <p>Now I have another Grape resource called Users(users.rb) and here I implement methods for authentication, registration and logout.(I think that I mix here apples with pears, and I should extract the login/logout process to another Grape resource - Session).</p>
  
  <pre><code>module API
    module V1
      class Users &lt; Grape::API
        include API::V1::Defaults
  
        resources :users do
          desc "Authenticate user and return user object, access token"
          params do
             requires :email, :type =&gt; String, :desc =&gt; "User email"
             requires :password, :type =&gt; String, :desc =&gt; "User password"
           end
           post 'authenticate' do
             email = params[:email]
             password = params[:password]
  
             if email.nil? or password.nil?
               error!({:error_code =&gt; 404, :error_message =&gt; "Invalid email or password."}, 401)
               return
             end
  
             user = User.find_by(email: email.downcase)
             if user.nil?
                error!({:error_code =&gt; 404, :error_message =&gt; "Invalid email or password."}, 401)
                return
             end
  
             if !user.valid_password?(password)
                error!({:error_code =&gt; 404, :error_message =&gt; "Invalid email or password."}, 401)
                return
             else
               user.ensure_authentication_token!
               user.save
               status(201){status: 'ok', token: user.authentication_token }
             end
           end
  
           desc "Register user and return user object, access token"
           params do
              requires :first_name, :type =&gt; String, :desc =&gt; "First Name"
              requires :last_name, :type =&gt; String, :desc =&gt; "Last Name"
              requires :email, :type =&gt; String, :desc =&gt; "Email"
              requires :password, :type =&gt; String, :desc =&gt; "Password"
            end
            post 'register' do
              user = User.new(
                first_name: params[:first_name],
                last_name:  params[:last_name],
                password:   params[:password],
                email:      params[:email]
              )
  
              if user.valid?
                user.save
                return user
              else
                error!({:error_code =&gt; 404, :error_message =&gt; "Invalid email or password."}, 401)
              end
            end
  
            desc "Logout user and return user object, access token"
             params do
                requires :token, :type =&gt; String, :desc =&gt; "Authenticaiton Token"
              end
              delete 'logout' do
  
                user = User.find_by(authentication_token: params[:token])
  
                if !user.nil?
                  user.remove_authentication_token!
                  status(200)
                  {
                    status: 'ok',
                    token: user.authentication_token
                  }
                else
                  error!({:error_code =&gt; 404, :error_message =&gt; "Invalid token."}, 401)
                end
              end
        end
      end
    end
  end
  </code></pre>
  
  <p>I realize that I present here a ton of code and it might not make sense, but this is what I currently have and I'm able to use the <code>authentication_token</code> for calls against my API which are protected by module <code>Authentication</code>.</p>
  
  <p>I feel like this solution is not good, but I really looking for easier way how to achieve user authentication through APIs. I have several questions which I listed below.</p>
  
  <p><strong>Questions</strong></p>
  
  <ol>
  <li>Do you think this kind of implementation is dangerous, if so, why? - I think that it is, because of the usage of one token. Is there a way how to improve this pattern? I've also seen implementation with separate model <code>Token</code>  which has expiration time, etc. But I think this is almost like reinventing wheel, because for this purpose I can implement OAuth2. I would like to have lighter solution.</li>
  <li>It is good practice to create new module for Authentication and include it only into resources where it is needed?</li>
  <li>Do you know about any good tutorial on this topic - implementing
  Rails + Devise + Grape? Additionally, do you know about any good
  open-source Rails project, which is implemented this way?</li>
  <li>How can I implement it with different approach which is more safer?</li>
  </ol>
  
  <p>I apologize for such a long post, but I hope that more people has the same problem and it might help me to find more answers on my questions.</p>