diff --git a/lib/omniauth/strategies/oauth2.rb b/lib/omniauth/strategies/oauth2.rb index 3ffff1b..86c8d5e 100644 --- a/lib/omniauth/strategies/oauth2.rb +++ b/lib/omniauth/strategies/oauth2.rb @@ -36,6 +36,24 @@ def client ::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options)) end + def callback_url + # If redirect_uri is configured in token_params, use that + # value. + token_params.to_hash(:symbolize_keys => true)[:redirect_uri] || super + end + + def query_string + # This method is called by callback_url, only if redirect_uri + # is omitted in token_params. + if request.params['code'] + # If this is a callback, ignore query parameters added by + # the provider. + '' + else + super + end + end + credentials do hash = {"token" => access_token.token} hash.merge!("refresh_token" => access_token.refresh_token) if access_token.expires? && access_token.refresh_token diff --git a/spec/omniauth/strategies/oauth2_spec.rb b/spec/omniauth/strategies/oauth2_spec.rb index 0bffcde..77fa482 100644 --- a/spec/omniauth/strategies/oauth2_spec.rb +++ b/spec/omniauth/strategies/oauth2_spec.rb @@ -87,6 +87,37 @@ def app instance.callback_phase end end + + describe "#callback_url" do + subject { fresh_strategy } + + it "returns the value in token_params, if given" do + instance = subject.new('abc', 'def', :token_params => {:redirect_uri => 'http://test/foo?bar=1'}) + allow(instance).to receive(:request) do + double('Request', :params => {'code' => 'codecodecode', 'state' => 'statestatestate'}) + end + expect(instance.callback_url).to eq('http://test/foo?bar=1') + end + + it "does not include any query parameters like 'code' and 'state'" do + instance = subject.new('abc', 'def') + allow(instance).to receive(:full_host) do + "http://test" + end + allow(instance).to receive(:script_name) do + '/foo' + end + allow(instance).to receive(:callback_path) do + '/bar/callback' + end + allow(instance).to receive(:request) do + double('Request', + :params => {'code' => 'codecodecode', 'state' => 'statestatestate'}, + :query_string => 'code=codecodecode&state=statestatestate') + end + expect(instance.callback_url).to eq('http://test/foo/bar/callback') + end + end end describe OmniAuth::Strategies::OAuth2::CallbackError do