devise_token_auth
devise_token_auth copied to clipboard
Unsafe redirect on signup [Rails 7.0]
- Version:
ruby '3.1.2'
gem 'devise_token_auth', git: 'https://github.com/lynndylanhurley/devise_token_auth.git', ref: '798255ee7e3fee5cfa2fdc519fd90e281bd9b6f5'
gem 'rails', '~> 7.0.3'
I am getting an UnsafeRedirectError at:
ActionController::Redirecting::UnsafeRedirectError: Unsafe redirect to "https://example.com/signup?auth_token=myAuthToken&blank=true&client_id=ClientID...", pass allow_other_host: true to redirect anyway.
File "/app/vendor/bundle/ruby/3.1.0/gems/actionpack-7.0.3/lib/action_controller/metal/redirecting.rb" line 193 in _enforce_open_redirect_protection
File "/app/vendor/bundle/ruby/3.1.0/gems/actionpack-7.0.3/lib/action_controller/metal/redirecting.rb" line 89 in redirect_to
File "/app/vendor/bundle/ruby/3.1.0/gems/actionpack-7.0.3/lib/action_controller/metal/instrumentation.rb" line 42 in block in redirect_to
File "/app/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.3/lib/active_support/notifications.rb" line 206 in block in instrument
File "/app/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.3/lib/active_support/notifications/instrumenter.rb" line 24 in instrument
File "/app/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.3/lib/active_support/notifications.rb" line 206 in instrument
File "/app/vendor/bundle/ruby/3.1.0/gems/actionpack-7.0.3/lib/action_controller/metal/instrumentation.rb" line 41 in redirect_to
File "/app/vendor/bundle/ruby/3.1.0/bundler/gems/devise_token_auth-798255ee7e3f/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb" line 232 in render_data_or_redirect
File "/app/vendor/bundle/ruby/3.1.0/bundler/gems/devise_token_auth-798255ee7e3f/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb" line 73 in omniauth_success
Adding config.action_controller.raise_on_open_redirects = false
to applcation.rb
would help, but redirect should be fixed I think.
@urbanrotnik I ran into the same issue. A quick workaround is to do a double redirect. Provide a same-host url to devise_token_auth that will route to one of your controller actions and you can route to whatever url you want. But now it's in your control.
@muyiwaoyeniyi could you share the changes you've done step by step 🙏 I know parameters should be passed but I'm confused enough trying to get the whole flow to work...
@malopez16 I can't put together a code snippet at the moment. This issue is happening because you're redirecting to a domain different from your server's domain. So here's what I did... set the redirect_url to a route on your server, then in the controller action for the route, you can redirect to the original/final url but add the allow_other_host flag... so
redirect_to FINAL_URL, allow_other_host: true
This goal here is to get devise token auth to redirect to a safe url (controller action) that is within your control and then from there you can redirect wherever you want.
Exactly, we monkey-patch device_token_auth as follow to add allow_other_host: true
Disclaimer: it's a quick and dirty solution.
config/initializers/devise_token_auth_monkey_patching.rb
Rails.configuration.to_prepare do
DeviseTokenAuth::ConfirmationsController.class_eval do
def show
@resource = resource_class.confirm_by_token resource_params[:confirmation_token]
if @resource.errors.empty?
yield @resource if block_given?
redirect_header_options = {account_confirmation_success: true}
if signed_in? resource_name
token = signed_in_resource.create_token
signed_in_resource.save!
redirect_headers = build_redirect_headers(token.token,
token.client,
redirect_header_options)
redirect_to_link = signed_in_resource.build_auth_url redirect_url, redirect_headers
else
redirect_to_link = DeviseTokenAuth::Url.generate redirect_url, redirect_header_options
end
redirect_to redirect_to_link, allow_other_host: true
else
redirect_to DeviseTokenAuth::Url.generate(redirect_url, account_confirmation_success: false), allow_other_host: true
end
end
end
end
I was having this same problem for the password reset flow. In my case, I just had to add allow_other_host: true
in my passwords controller, as the default redirect in the DeviseTokenAuth::PasswordsController
has a redirect_options hash. Not sure why the confirmations controller doesnt
class Auth::PasswordsController < DeviseTokenAuth::PasswordsController
private
def resource_params
params.permit(:email, :reset_password_token, :config, :redirect_url)
end
def redirect_options
{
allow_other_host: true
}
end
end