plataformatec/devise — Issue #1532: [master] double queries during http auth/auth_token
Author: masterkain
Created: 2011-12-29 16:57:24+00:00
State: open

Hi,
I have a model Account and three subclasses, two being User and Company. All the subclasses are defined in routes.rb.

Given an API controller, I get this during http basic auth:

# config.http_authenticatable = true

Started GET "/api/playlists" for 127.0.0.1 at 2011-12-29 17:44:06 +0100
Processing by Api::V1::PlaylistsController#index as XML
User Load (2.5ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('User') AND `accounts`.`authentication_token` = 'masterkain@gmail.com' LIMIT 1
User Load (0.6ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('User') AND `accounts`.`email` = 'masterkain@gmail.com' LIMIT 1
(0.1ms) BEGIN
(0.5ms) UPDATE `accounts` SET `last_sign_in_at` = '2011-12-29 16:43:53', `current_sign_in_at` = '2011-12-29 16:44:07', `sign_in_count` = 72, `updated_at` = '2011-12-29 16:44:07' WHERE `accounts`.`type` IN ('User') AND `accounts`.`id` = 2
(0.8ms) COMMIT
Company Load (0.5ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('Company') AND `accounts`.`authentication_token` = 'masterkain@gmail.com' LIMIT 1
Company Load (0.4ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('Company') AND `accounts`.`email` = 'masterkain@gmail.com' LIMIT 1
Playlist Load (0.9ms) SELECT `playlists`.* FROM `playlists` WHERE `playlists`.`account_id` = 2 ORDER BY playlists.position ASC
Completed 200 OK in 59ms (Views: 3.6ms | ActiveRecord: 0.9ms)

First thing to notice is that somehow if :token_authenticatable is enabled it will try to match the username portion of http auth as the authentication_token, which should already be email in first place, in my opinion.

Second: sign in data gets updated on every API hit. This may not be desiderable and I'm looking for a way to disable that in some controllers, pointers appreciated.

Third: for some unknown reason it also tries to query the Company model, for which by double checking, has nothing to do with the code portion I'm currently writing.

Fourth: I have another deviseable subclass, which for some reason it doesn't load as Company does, this led me thinking about an error or a wrong reference in my code, but it does not seem to be the case.

Authenticating directly with auth_token in URL it is slighly better, but Company still loads:

Started GET "/api/playlists?auth_token=3syWP5DZ9etRFHxNDCp3" for 127.0.0.1 at 2011-12-29 17:52:13 +0100
Processing by Api::V1::PlaylistsController#index as XML
Parameters: {"auth_token"=>"3syWP5DZ9etRFHxNDCp3"}
User Load (20.5ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('User') AND `accounts`.`authentication_token` = '3syWP5DZ9etRFHxNDCp3' LIMIT 1
(0.3ms) BEGIN
(20.5ms) UPDATE `accounts` SET `last_sign_in_at` = '2011-12-29 16:52:13', `current_sign_in_at` = '2011-12-29 16:52:13', `last_sign_in_ip` = '127.0.0.1', `current_sign_in_ip` = '127.0.0.1', `sign_in_count` = 1, `updated_at` = '2011-12-29 16:52:13' WHERE `accounts`.`type` IN ('User') AND `accounts`.`id` = 13569
(37.1ms) COMMIT
Company Load (0.7ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`deleted_at` IS NULL AND `accounts`.`type` IN ('Company') AND `accounts`.`authentication_token` = '3syWP5DZ9etRFHxNDCp3' LIMIT 1
Playlist Load (1.6ms) SELECT `playlists`.* FROM `playlists` WHERE `playlists`.`account_id` = 13569 ORDER BY playlists.position ASC

The deleted_at you see is a scope for soft-delete support.

Controller code is very simple, api controllers inherits from this:

class Api::HomeController < ApplicationController
before_filter :authenticate_user!

I'm using devise master, with devise.rb updated to the latest settings, like:

config.skip_session_storage = [:http_auth, :token_auth]