From 87b11fca10d22de95b39f321631a16d3a3e8ac2d Mon Sep 17 00:00:00 2001 From: Ben Standefer Date: Wed, 17 Mar 2021 20:45:04 -0700 Subject: [PATCH] Add config to not create new clients on standard Devise requests If `enable_standard_devise_support` is `true`, XHR requests that rely on standard Devise authentication (i.e. a logged in session) seemed to inadvertently create new client instances. This meants if you have a high volume of XHR requests to an ApplicationController that uses devise_token_auth, if those clients don't respect/use the devise_token_auth headers, soon those clients will cause devise_token_auth to rotate out all its tokens, leaving other clients with invalid tokens. This adds a config `standard_devise_dont_create_new_client` that defaults to `false` (previous behavior), but if you want XHR requests using standard Devise to not rotate clients/tokens, setting `standard_devise_dont_create_new_client` will return early, before devise_token_auth gets to the token rotation. --- .../devise_token_auth/concerns/set_user_by_token.rb | 6 ++++++ lib/devise_token_auth/engine.rb | 2 ++ 2 files changed, 8 insertions(+) diff --git a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb index a2221b010..bbd724a21 100644 --- a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +++ b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb @@ -15,6 +15,7 @@ module DeviseTokenAuth::Concerns::SetUserByToken def set_request_start @request_started_at = Time.zone.now @used_auth_by_token = true + @standard_devise_dont_create_new_client = false # initialize instance variables @token ||= DeviseTokenAuth::TokenFactory.new @@ -58,6 +59,7 @@ def set_user_by_token(mapping = nil) devise_warden_user = warden.user(mapping) if devise_warden_user && devise_warden_user.tokens[@token.client].nil? @used_auth_by_token = false + @standard_devise_dont_create_new_client = true @resource = devise_warden_user # REVIEW: The following line _should_ be safe to remove; # the generated token does not get used anywhere. @@ -94,6 +96,10 @@ def set_user_by_token(mapping = nil) end def update_auth_header + if DeviseTokenAuth.standard_devise_dont_create_new_client && @standard_devise_dont_create_new_client + return + end + # cannot save object if model has invalid params return unless @resource && @token.client diff --git a/lib/devise_token_auth/engine.rb b/lib/devise_token_auth/engine.rb index e6a921aa9..944199e93 100644 --- a/lib/devise_token_auth/engine.rb +++ b/lib/devise_token_auth/engine.rb @@ -22,6 +22,7 @@ class Engine < ::Rails::Engine :redirect_whitelist, :check_current_password_before_update, :enable_standard_devise_support, + :standard_devise_dont_create_new_client, :remove_tokens_after_password_reset, :default_callbacks, :headers_names, @@ -43,6 +44,7 @@ class Engine < ::Rails::Engine self.redirect_whitelist = nil self.check_current_password_before_update = false self.enable_standard_devise_support = false + self.standard_devise_dont_create_new_client = false self.remove_tokens_after_password_reset = false self.default_callbacks = true self.headers_names = { 'access-token': 'access-token',