diff --git a/README.md b/README.md index 0905e18..2961313 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ Rails.application.config.middleware.use OmniAuth::Builder do scope: 'email name', team_id: ENV['TEAM_ID'], key_id: ENV['KEY_ID'], - pem: ENV['PRIVATE_KEY'] + pem: ENV['PRIVATE_KEY'], + nonce: :session # :session, :param, or :ignore. Set this to ":param" in an API only backend } end ``` diff --git a/lib/omniauth/strategies/apple.rb b/lib/omniauth/strategies/apple.rb index 347afc2..96ea1e1 100644 --- a/lib/omniauth/strategies/apple.rb +++ b/lib/omniauth/strategies/apple.rb @@ -20,6 +20,8 @@ class Apple < OmniAuth::Strategies::OAuth2 scope: 'email name' option :authorized_client_ids, [] + option :nonce, :session # :session, :param, or :ignore + uid { id_info[:sub] } # Documentation on parameters @@ -70,11 +72,28 @@ def authorized_client_ids end def new_nonce - session['omniauth.nonce'] = SecureRandom.urlsafe_base64(16) + nonce = SecureRandom.urlsafe_base64(16) + case options.nonce + when :session + session['omniauth.nonce'] = nonce + end + nonce end def stored_nonce - session.delete('omniauth.nonce') + case options.nonce + when :session + session.delete('omniauth.nonce') + when :param + request.params['nonce'] + end + end + + def verify_nonce!(id_token) + return true if options.nonce == :ignore + raise ArgumentError, "Invalid nonce option: #{options.nonce}. Must be :session, :param, or :ignore" unless [:session, :param].include?(options.nonce) + + invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce end def id_info @@ -128,10 +147,6 @@ def verify_exp!(id_token) invalid_claim! :exp unless id_token[:exp] >= Time.now.to_i end - def verify_nonce!(id_token) - invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce - end - def invalid_claim!(claim) raise CallbackError.new(:id_token_claims_invalid, "#{claim} invalid") end