Simple Token Authentication for Rails JSON API

I have a Rails application (it is mostly JSON API) I am using Devise to authenticate using a JSON request from any source (web, mobile) and I am using Simple Token Authentication to authenticate users using HTTP headers.

I'm not sure what the implementation should look like, but I've come up with an implementation that almost works.

There is only one problem. and this is when the user tries to log out ... Usually it should revoke the authentication token for the user ... but it is not, I am not sure where the problem really is ... whether it works with Devise or Simple Token Auth ... so any help is greatly appreciated.

but here is the code

  # router
  devise_for :users, controllers: { sessions: 'sessions',
                                    registrations: 'registrations' }
  api vendor_string: 'app', default_version: 1, path: '', format: 'json' do
    version 1 do
      cache as: 'v1' do
        resource :some_resource
      end
    end

      

the session controller is like this

class SessionsController < Devise::SessionsController  
  respond_to :json
  skip_filter :verify_signed_out_user, only: :destroy

  def create
    self.resource = warden.authenticate!(scope: resource_name)
    render :create, status: :created
  end

  def destroy
    current_user.authentication_token = nil
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ take note of this line
    current_user.save!
    super
  end
end  

      

the previous marked line seems to have a problem ... when the user provides the wrong token header, it still works and the current user is referencing a user that should not be authenticated in the first place .. eg here 2 calls, spec

describe 'DELETE sessions#destroy' do
    let(:user) { Fabricate(:confirmed_user) }
    let(:auth_token) { user.authentication_token }
    describe 'with request headers' do
      context 'valid credentials' do
        it 'Returns 204' do
          delete '/users/sign_out', {}, {
            HTTP_CONTENT_TYPE: 'application/json',
            HTTP_ACCEPT: "application/vnd.app+json; version=1",
            "X-User-Email" => user.email,
            "X-User-Token" => user.authentication_token
          }

          user.reload
          expect(response.status).to eq 204
          expect(user.authentication_token).not_to eq auth_token
          #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is ok cause it the valid user
        end
      end

      context 'invalid credentials' do
        it 'Returns 204' do
          delete '/users/sign_out', {}, {
            HTTP_CONTENT_TYPE: 'application/json',
            HTTP_ACCEPT: "application/vnd.app+json; version=1",
            "X-User-Email" => user.email,
            "X-User-Token" => 'Invalid'
          }

          user.reload
          expect(response.status).to eq 204
          expect(user.authentication_token).to eq auth_token
          #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this FAILS
          # why did the user get new auth token when didn't sign out ????
        end
      end
    end

      

this is also reported on github

and for completeness, here is the application controller

class ApplicationController < ActionController::Base
  # The API responds only to JSON
  respond_to :json

  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  # default to protect_from_forgery with: :exception
  protect_from_forgery with: :null_session

  # Token Authenticatable for API
  acts_as_token_authentication_handler_for User
end

      

+3


source to share


2 answers


From the simple_authentication_token page on github, it current_user.authentication_token

will be automatically generated if it was empty (zero) every time current_user is saved.

Assuming the user is a user instance that is the token authenticate: every time the user is saved and user.authentication_token.blank? he receives a new and unique authentication token (via Devise.friendly_token).



Update

Add acts_as_token_authentication_handler_for User

to yoursessions_controller.rb

+1


source


Please read https://github.com/gonzalo-bulnes/simple_token_authentication/issues/224 . I believe this is normal behavior. You need to remove the token on the client side (device)



0


source







All Articles