Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Override devise's TokenAuthenticatable strategy to use Authorization headers

This will allow you to use devise's TokenAuthenticatable strategy while passing your :auth_token in using HTTP Authorization headers instead of params.

You can check it out using

curl -H "Authorization: Token token=XXXXXX, option=1" -vv http://railsapp.dev/api/v1/endpoint.json

It should properly authenticate using the token as well as set request.env['token.options'] to {"options" => "1"}.

# File: lib/devise/strategies/api_authenticatable.rb
require 'devise/strategies/token_authenticatable'
module Devise
module Strategies
class ApiAuthenticatable < TokenAuthenticatable
private
# Try to rip out authorization and override our authentication_key
def params_auth_hash
return_params = super
token_key = mapping.to.token_authentication_key
token = ActionController::HttpAuthentication::Token
.token_and_options(request)
if token
return_params.merge! token_key => token.first
request.env['token.options'] = token.last || {}
end
return_params
end
end
end
end
Warden::Strategies.add(
:api_authenticatable,
Devise::Strategies::ApiAuthenticatable
)
# File: config/initializers/devise.rb
require 'devise/strategies/api_authenticatable'
Devise.setup do |config|
# ...
config.warden do |manager|
manager.default_strategies(:scope => :user).unshift :api_authenticatable
end
# ...
end
describe 'authenticating with Authorization header' do
let(:token_key){ Devise.token_authentication_key }
let!(:user){ create :user }
let(:token){ user.authentication_token }
controller(described_class) do
def index
head :ok
end
end
before do
request.env['HTTP_AUTHORIZATION'] =
ActionController::HttpAuthentication::Token.encode_credentials(
token, {hello: 'world'})
end
it 'sets env[token.options]' do
json_get :index
request.env['token.options'] == {'hello' => 'world'}
end
context 'when auth_token param is missing' do
it 'sets the auth token from Authorization header' do
json_get :index
controller.params[token_key].should eq token
response.should be_success
end
end
context 'when auth_token param is present' do
it 'it overrides the param' do
json_get :index, auth_token: 'bad token'
controller.params[token_key].should eq token
response.should be_success
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment