Giter Site home page Giter Site logo

omniauth-apple's Introduction

build

OmniAuth::Apple

OmniAuth strategy for Sign In with Apple.

Installation

Add this line to your application's Gemfile:

gem 'omniauth-apple'

And then execute:

$ bundle

Or install it yourself as:

$ gem install omniauth-apple

Usage

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :apple, ENV['CLIENT_ID'], '',
           {
             scope: 'email name',
             team_id: ENV['TEAM_ID'],
             key_id: ENV['KEY_ID'],
             pem: ENV['PRIVATE_KEY']
           }
end

Configuring "Sign In with Apple"

other Sign In with Apple guides:

Look out for the values you need for your config

  1. your domain and subdomains, something like: myapp.com, www.myapp.com
  2. your redirect uri, something like: https://myapp.com/users/auth/apple/callback (check rails routes to be sure)
  3. omniauth's "client id" will be Apple's "bundle id", something like: com.myapp
  4. you will get the "team id" value from Apple when you create your App Id, something like: H000000B
  5. Apple will give you a .p8 file, which you'll use to GENERATE your :pem value

Steps

  1. Log into your Apple Developer Account (if you don't have one, you can create one here)

  2. Get an App Id with the "Sign In with Apple" capability

    • go to your Identifiers list
    • start a new Identifier by clicking on the + sign in the Identifiers List
    • select App IDs and click continue
    • select App and continue
    • enter a description and a bundle id
    • check the "Sign In with Apple" capability
    • save it
  3. Get a Services Id (which we will use as our client id)

  4. Get a Secret Key

    • go to your Keys list
    • start a new Key by clicking on the + sign in the Keys List
    • enter a name
    • make sure "Sign In with Apple" is checked, then click configure
    • make sure the Primary App ID matches the App ID you configured earlier
    • save the "Sign In with Apple" capability
    • click "continue" to finish the Key config (you will be prompted to Download Your Key)
    • Apple will give you a .p8 file, keep it safe and secure (don't commit it).

Mapping Apple Values to OmniAuth Values

  • your :team_id is in the top-right of your App Id config (aka App ID Prefix), it looks like: H000000B

  • your :client_id is in the top-right of your Services Id config (aka Identifier), it looks like: com.example

  • your :key_id is on the left side of your Key Details page, it looks like: XYZ000000

  • your :pem is the content of the .p8 file you got from Apple, with an extra newline at the end

  • example from a Devise config:

      config.omniauth :apple, ENV['APPLE_SERVICE_BUNDLE_ID'], '', {
        scope: 'email name',
        team_id: ENV['APPLE_APP_ID_PREFIX'],
        key_id: ENV['APPLE_KEY_ID'],
        pem: ENV['APPLE_P8_FILE_CONTENT_WITH_EXTRA_NEWLINE']
      }

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/nhosoya/omniauth-apple.

License

The gem is available as open source under the terms of the MIT License.

omniauth-apple's People

Contributors

btalbot avatar dependabot-preview[bot] avatar dipth avatar dzunk avatar fjaeger avatar lucas-aragno avatar maxencehenneron avatar mikker avatar nalabjp avatar nhosoya avatar nov avatar tylerkahn avatar wilg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omniauth-apple's Issues

What is PRIVATE_KEY ?

Sorry i dont understand what is the PRIVATE_KEY, i mean its the key that i generate from the console in .p8 ?

redirect_uri doesn't trigger redirect

When using omniauth-facebook or omniauth-google-oauth2 you can pass in a redirect_uri so that the callback triggers a redirect. I know for facebook you have to pass in the callback_url in the config, but neither option appears to work with omniauth-apple. Any suggestions or does this need to be added?

Support login from iOS app

Hi,

I am currently developing an iOS app that connects to an API on Rails, using devise + OmniAuth for user sign-ups/logins.

While trying to use omniauth-apple to handle Sign In with Apple requests I noticed this path doesn't seem to be handled. The gem seems to only allow logins from the web.

I have successfully integrated the iOS app by using the following:

  1. updated configuration in initializers/devise.rb
  config.omniauth :apple, 'web-service-id', '',
                  authorized_client_ids: ['ios-app-id'],
                  scope: 'email name',
                  team_id: 'team-id',
                  key_id: 'key-id',
                  pem: 'p8 content',
                  provider_ignores_state: true
  1. Altered my user.rb model to add :apple to the existing :omniauth_providers

  2. Add a path for apple callback in omniauth_callbacks_controller.rb

  3. I also had to insert the following into libomniauth/strategies/apple.rb :

      protected

      def build_access_token
        if request.params["id_token"]
          return ::OAuth2::AccessToken.from_hash(client, { access_token: request.params["id_token"] })
        else
          super
        end
      end
  1. the iOS app sends a GET request to https://example.com/api/users/auth/apple/callback with two query params :
    • id_token: obtained from authorization.credential as? ASAuthorizationAppleIDCredential
    • user: associated to a JSON string like so :
{
    "name": {
        "firstName": ''", // obtained from creds.fullName?.givenName
        "lastName": ''" // obtained from creds.fullName?.familyName
    }
}

I was wondering if the point 4. could be supported directly by this gem ? I am not sure I'd be able to send a PR as I haven't worked on building gems yet, but I could provide you with more info if needed.

Thanks !

JWT::DecodeError

I am able to get redirected to the apple sign-in page where I have to sign into my Apple ID and grant my app permission. However, when I am redirected back to my rails app I receive the following error:

JWT::DecodeError No verification key available

It would appear something is going wrong with the jwt configurations, however, this library does not specify any configurations for such. What would the solution for this be?

Apple SSO Callback Phase throws a OAuth2::AccessToken.from_hash error

I am trying to implement Apple SSO using the omniauth_apple gem in Ruby on Rails.

In my devise.rb, i have the following config

config.omniauth :apple, Rails.application.credentials.dig(Rails.env.to_sym, :apple_sso, :client_id), '', {
        scope: 'email name',
        team_id: Rails.application.credentials.dig(Rails.env.to_sym, :apple_sso, :team_id),
        key_id: Rails.application.credentials.dig(Rails.env.to_sym, :apple_sso, :key_id),
        pem: Rails.application.credentials.dig(Rails.env.to_sym, :apple_sso, :pem),
        redirect_uri: Rails.application.credentials.dig(Rails.env.to_sym, :apple_sso, :redirect_uri),
        provider_ignores_state: true
      }

In my omniauth_callbacks_controller.rb, i have the following

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    skip_before_action :verify_authenticity_token, only: [:apple]
    protect_from_forgery prepend: true, only: :apple
    
    def apple
      puts "==== GOT INTO APPLE======="
      auth_hash = request.env['omniauth.auth']
    end
  end

My user.rb

class User < ApplicationRecord
   acts_as_tenant(:tenant)
 
   devise :database_authenticatable, :registerable, :recoverable, :lockable,
     :timeoutable, :rememberable, :trackable, :confirmable, :zxcvbnable,
     :omniauthable, :jwt_authenticatable,
     jwt_revocation_strategy: JwtDenyList, omniauth_providers: [:google_oauth2, :facebook, :apple]
 end

in my routes, i also have specification to receive callbacks for each provider

devise_for :users,
       only: :omniauth_callbacks,
       controllers: {omniauth_callbacks: "users/omniauth_callbacks"}

Now when i click the Sign in with Apple button, it does redirect me to sign in my username and password from Apple but when the callback phase is initiated, it returns an error and does not redirect to the controller. I get this error but I honestly do not know how or where to start to resolve it

    OAuth2::AccessToken.from_hash: `hash` contained more than one 'token' key (["access_token", "id_token"]); using "access_token".
    (apple) Authentication failure! invalid_credentials: OmniAuth::Strategies::OAuth2::CallbackError, id_token_claims_invalid | nonce invalid

Does anyone have experience using the omniauth_apple gem with Devise to setup and fully integrate Apple SSO on Rails? Please help

Oauth2 version 2.0.0 breaks omniauth-apple

Specifically this line in the Oauth2 2.0.0 release changelog breaks omniauth-apple gem:

"oauth-xx/oauth2#312 - BREAKING: Set :basic_auth as default for :auth_scheme instead of :request_body. This was default behavior before 1.3.0. (@tetsuya, @wy193777)

Apple get token call needs the "client_id" and "client_secret" in the body, which will only be sent if Oauth2 "auth_scheme" type is ":request_body"

Please provide a fix or advice how we can set the :auth_scheme to :request_body through omniquth options.
Thanks

Use jwt gem instead of json-jwt

The jwt gem is a more popular implementation than the json-jwt gem currently in use. It's also a required dependency of oauth2 through omniauth-oauth2, so it will already be present in the bundle. By switching to the jwt gem, we can avoid an additional dependency that duplicates existing functionality.

Stuck on Request Phase Initiated

In my logs I get stuck on:
DEBUG -- omniauth: (apple) Request phase initiated.

Routes:

GET|POST /users/auth/apple(.:format)
GET|POST /users/auth/apple/callback(.:format)

omniauth controller:

def apple
    @user = User.from_omniauth(request.env['omniauth.auth'])
    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication
      set_flash_message(:notice, :success, kind: 'apple') if is_navigational_format?
    else
      session['devise.apple_data'] = request.env['omniauth.auth'].except(:extra)
      redirect_to new_user_registation_url
    end
  end

devise initalizer:

config.omniauth :apple, Rails.application.credentials.apple[:client_id], '',
                  {
                    scope: 'email name',
                    team_id: Rails.application.credentials.apple[:team_id],
                    key_id: Rails.application.credentials.apple[:key_id],
                    pem: OpenSSL::PKey::EC.new(Rails.application.credentials.apple[:secret_key]).to_pem,
                    callback_path: "/users/auth/apple/callback",
                    authorized_client_ids: Rails.application.credentials.apple[:client_id],
                    provider_ignores_state: true
                  }

I had a problem with no curve for nil class which was solved by passing the key as pem properly, but now I can't get past request phase initiated..

user_cancelled_authorize: OmniAuth::Strategies::OAuth2::CallbackError, user_cancelled_authorize

Seems that this gem results in a OmniAuth::Strategies::OAuth2::CallbackError being raised when the user cancels the Sign in with Apple flow, after supplying their credentials, when presented with the Cancel / Continue buttons.

Here appears to be some relevant code in omniauth-oauth2: https://github.com/omniauth/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb#L66-L83

Wondering if this is something this gem should explicitly try to suppress.

OmniAuth infoHash returns email as nil

Hello,

I am experiencing a curious bug where the OmniAuth info hash returns email as nil for every Apple user that owns an iPhone that uses Face ID for authentication (iPhone X and above):

info=#<OmniAuth::AuthHash::InfoHash email=nil first_name=nil last_name=nil sub="001474.c261...."> provider="apple" uid="001474.c261..."

When I try the sign in, using Touch ID for authentication (iPhone 6s), it returns my valid email address in it, as it should be:

info=#<OmniAuth::AuthHash::InfoHash email="[email protected]" first_name=nil last_name=nil sub="001273.a95..."> provider="apple" uid="001273.a95ed...">

Why is it that it returns nil when Face ID is used?

I attach some screenshots below of the flow I'm taking about:




Thanks!

ActiveSupport now required for with_indifferent_access?

I'm just starting out with this gem but is RoR / ActiveSupport really required for this now? Most other omniauth providers avoid this to keep them light.

This seems to have been changed 7 days ago. There might be more but this one raises an error now.

I, [2020-06-15T23:38:09.212064 #6]  INFO -- : (apple) Callback phase initiated.
E, [2020-06-15T23:38:09.970140 #6] ERROR -- : app error: undefined method `with_indifferent_access' for #<Hash:0x0000559ad6939fb0> (NoMethodError)
E, [2020-06-15T23:38:09.970196 #6] ERROR -- : /usr/local/bundle/bundler/gems/omniauth-apple-9db5dc4acf5a/lib/omniauth/strategies/apple.rb:79:in `map'
E, [2020-06-15T23:38:09.970209 #6] ERROR -- : /usr/local/bundle/bundler/gems/omniauth-apple-9db5dc4acf5a/lib/omniauth/strategies/apple.rb:79:in `fetch_jwks'
E, [2020-06-15T23:38:09.970219 #6] ERROR -- : /usr/local/bundle/bundler/gems/omniauth-apple-9db5dc4acf5a/lib/omniauth/strategies/apple.rb:68:in `id_info'
E, [2020-06-15T23:38:09.970228 #6] ERROR -- : /usr/local/bundle/bundler/gems/omniauth-apple-9db5dc4acf5a/lib/omniauth/strategies/apple.rb:19:in `block in <class:Apple>'

Nonce mismatch Error

Any idea what might be causing this error? Everything seems to be "wired" correctly when I login into my web app. But I see this flash message.
Could not authenticate you from Apple because "Nonce mismatch".

One thing I noticed if I change :lax to :none, the error goes away. However, it no longer works in Chrome. Not ideal.
config.action_dispatch.cookies_same_site_protection = :lax

Logs:
ERROR -- omniauth: (apple) Authentication failure! nonce_mismatch: OmniAuth::Strategies::OAuth2::CallbackError, nonce_mismatch | nonce mismatch

Can someone help explain refresh tokens to me?

I was reading through the Apple documentation on Verifying a User and it specifically talks about refresh tokens being used "to obtain access tokens with future calls."

I know that I am receiving a refresh_token in the response I get from Apple after authenticating, but I'm not seeing any reference to refresh tokens in this library. Am I missing something? Does this omniauth strategy automatically use refresh tokens? How do I implement it? Do I need to use a different library for that?

I am fairly new to omniauth / Apple SSO, so any and all help is much appreciated.

Thanks!

#<OpenSSL::PKey::ECError: invalid curve name>

Hey, can I get some help to determine the issue?

Describe the bug

{
    "status": 500,
    "error": "Internal Server Error",
    "exception": "#<OpenSSL::PKey::ECError: invalid curve name>",
    "traces": {
        "Application Trace": [],
        "Framework Trace": [
            {
                "id": 0,
                "trace": "/home/david/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/bundler/gems/omniauth-apple-8c1fba1ad680/lib/omniauth/strategies/apple.rb:83:in `initialize'"
            },
            {
                "id": 1,
                "trace": "/home/david/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/bundler/gems/omniauth-apple-8c1fba1ad680/lib/omniauth/strategies/apple.rb:83:in `new'"
            },
            {
                "id": 2,
                "trace": "/home/david/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/bundler/gems/omniauth-apple-8c1fba1ad680/lib/omniauth/strategies/apple.rb:83:in `private_key'"
            },
            {
                "id": 3,
                "trace": "/home/david/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/bundler/gems/omniauth-apple-8c1fba1ad680/lib/omniauth/strategies/apple.rb:79:in `client_secret'"
            },
            {
                "id": 4,
                "trace": "/home/david/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/bundler/gems/omniauth-apple-8c1fba1ad680/lib/omniauth/strategies/apple.rb:35:in `client'"
           }
}

To Reproduce

config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :apple, ENV['APPLE_CLIENT_ID'], '', { scope: 'email name', team_id: ENV['APPLE_TEAM_ID'], key_id: ENV['APPLE_KEY'], pem: ENV['APPLE_PEM'] }
end

Environment variables are stored using Figaro:

APPLE_CLIENT_ID: "com.myapp.client"
APPLE_TEAM_ID: "DX4RM9AL52"
APPLE_KEY: "51KDRS24J5"
APPLE_PEM: "-----BEGIN PRIVATE KEY-----\nMIGTAgEAmBMGByqGSM49AgEgCCqGSM49AwEHBHkwdwIBAQQgsO8K8Jbcp3mJIoSu\n+HPFYiW1jNaa+MvTHxKj7Hb+b++gCgYIKoZIzj0DAQehRANCAARxcsMPCg29tjBN\nxPJ3EEpVqz4/rH/ExZSKwaIZ/nCtkvtPUS7Y7IHaBVB94OyimoPpaz4HNzppD3UE\npYRfzHK+\n-----END PRIVATE KEY-----"

Expected behavior

Additional context

  • Environment variables are NOT the real ones.
  • I changed the .p8 format to a .txt and edited the code in gedit to add the \n
  • This helped to find out how to store the pem key in Figaro
  • This talks about the same problem (invalid curve) but a different set-up

Please, add to Readme some important settings.

For rails 7.1.3

In config/application.rb:
config.action_dispatch.cookies_same_site_protection = lambda { |request|
request.path == '/users/auth/apple' ? :none : :lax
}

In controllers/application_controller.rb:
def verified_request?
controller_name == 'omniauth_callbacks' || super
end

In config/environments/production.rb:
config.assume_ssl = true
config.force_ssl = true

Without these settings the gem did not work for me.
Hope this helps others.

nonce is optional in callback

In releases before 1.3, the nonce appearing in the id_token was optional and if present was required to be equal to the nonce in the session['omniauth.nonce'] value. That changed in the 1.3 release where the nonce is now required in the id_token and is an error when missing.

My reading of the apple developer docs is that the nonce is an optional feature and may not appear in the id_token. Their wording makes it sounds like the nonce might be useful for locating a user session if the session cookie wasn't received for some reason (like maybe with non-lax cookies and their POST from a different origin).

https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple

nonce
A string for associating a client session with the identity token. This value mitigates replay attacks and is present only if you pass it in the authorization request.

nonce_supported
A Boolean value that indicates whether the transaction is on a nonce-supported platform. If you send a nonce in the authorization request, but don’t see the nonce claim in the identity token, check this claim to determine how to proceed. If this claim returns true, treat nonce as mandatory and fail the transaction; otherwise, you can proceed treating the nonce as optional.

The nonce can be made to be optional and still enforce the expected value by simply not first requiring that the id_token[:nonce] value exists.

diff --git a/lib/omniauth/strategies/apple.rb b/lib/omniauth/strategies/apple.rb
index 5ad3a40..faf8e0e 100644
--- a/lib/omniauth/strategies/apple.rb
+++ b/lib/omniauth/strategies/apple.rb
@@ -125,7 +125,7 @@ module OmniAuth
       end

       def verify_nonce!(id_token)
-        invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce
+        invalid_claim! :nonce unless id_token[:nonce] == stored_nonce
       end

       def invalid_claim!(claim)

I have a spec test for this path coded up but it doesn't fit very nicely into the current test descriptions and contexts as most of those all force a nonce to be present. But here is a spec test that fails without the patch above and passes with it.

diff --git a/spec/omniauth/strategies/apple_spec.rb b/spec/omniauth/strategies/apple_spec.rb
index 2709d1b..10e56ec 100644
--- a/spec/omniauth/strategies/apple_spec.rb
+++ b/spec/omniauth/strategies/apple_spec.rb
@@ -79,6 +79,16 @@ describe OmniAuth::Strategies::Apple do
     WebMock.reset!
   end

+  it 'allows optional nonce' do
+    subject.authorize_params # initializes env, session (for test_mode) and populates 'nonce', 'state'
+    subject.session.delete('omniauth.nonce')  # if no nonce in session => nonce in id_token must also be missing
+    request.params.merge!('id_token' => id_token)
+    expect(valid_id_token_payload).not_to have_key(:nonce)
+    expect { subject.info }.not_to raise_error
+    expect(subject.extra.dig(:raw_info, :id_info, 'nonce_supported')).to eq true
+    expect(subject.extra.dig(:raw_info, :id_info, 'nonce')).to be nil
+  end
+
   describe '#client_options' do
     it 'has correct site' do
       expect(subject.client.site).to eq('https://appleid.apple.com')

session variable is empty

I'm trying to use this Gem in Rails API with devise_token_auth, but it didn't work.

It seems that session variable is empty. In the case of Google or Facebook, can see the value in the session variable.

Is this a bug in Gem? I would like to know if there is a way to fix it.

Some people seem to have encountered similar cases. ref

I'm trying this one too. ref

Getting error as id_token_claims_invalid | nonce invalid

Hi,

I tried to set up the apple login and signup using omni-auth apple gem in my application.

# config/initializers/omniauth.rb:

I want to get the id_token from the response because I need the user email every time while hitting this URL

  provider :apple, Rails.application.credentials[:apple_client_id] // ID from service's bundler (eg: com.domain.api), '',
             authorized_client_ids: [Rails.application.credentials[:apple_ui_client_id]] // ID from app's identifier (eg: com.domain.app),
             scope: 'email name',
             team_id: Rails.application.credentials[:apple_team_id],
             key_id: Rails.application.credentials[:apple_key_id],
             pem: Rails.application.credentials[:apple_private_key] // add the pem content with an extra newline at the end,
             provider_ignores_state: true

Error returns:

Authentication failure! invalid_credentials: OmniAuth::Strategies::OAuth2::CallbackError, id_token_claims_invalid | nonce invalid

Please help me to sort out this error.

Fetching keys fails in production

in production, fetch_jwks fails with a 403 error

I don't think it is a problem with my server as running simple curl from the server works fine

curl https://appleid.apple.com/auth/keys
> returns keys

opening the rails console and using Net:HTTP

Loading production environment (Rails 6.1.3)
irb(main):001:0> uri = URI.parse('https://appleid.apple.com/auth/keys')
=> #<URI::HTTPS https://appleid.apple.com/auth/keys>
irb(main):002:0> response = Net::HTTP.get_response(uri)
=> #<Net::HTTPForbidden 403 Forbidden readbody=true>
irb(main):003:0> response.body
=> "<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body>\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>Apple</center>\r\n</body>\r\n</html>\r\n"

any ideas?

Apple's /auth/revoke supported?

Is Apple's /auth/revoke supported? Depending on the app's flow, this may be required for apps submitted by June 30, 2022. Reference: https://developer.apple.com/documentation/sign_in_with_apple/revoke_tokens

Error when callback ?

I am using this gem together with Devise for 'Sign in with Apple' feature from my web. Everything work fine when redirect to Apple Sign in page. But after succesful sign in, a callback to my web and error happen ( in local enviroment ).
I only can fix this error if add protect_from_forgery prepend: true, only: :apple to the top of OmniauthCallbacksController. But I dont think this is the right way to fix it.

image

Documentation is lacking

This project needs thorough documentation. I've been trying to get it to work for the last week with no success. Comparing the source code to omniauth-facebook, omniauth-apple appears to work quite differently.

How to retrieve email and name?

After having received an access token, how would we get the user's email or name that we initially requested via the scopes?

I could not find any details about that part of the authentication from Apple...

Authentication failure! no implicit conversion of String into Array: TypeError, no implicit conversion of String into Array

I can successfully authenticate with apple, but then the callback fails with the following error:

(apple) Request phase initiated.
Started POST "/api/users/auth/apple/callback" for 114.125.77.150 at 2023-02-17 12:13:04 +0700
Cannot render console from 114.125.77.150! Allowed networks: 127.0.0.0/127.255.255.255, ::1
(apple) Callback phase initiated.
(apple) Authentication failure! no implicit conversion of String into Array: TypeError, no implicit conversion of String into Array
Processing by Users::OmniauthCallbacksController#failure as HTML
Parameters: {"state"=>"59267181a968b7e95a8b940649ea747aee9168b2666c668a", "code"=>"[FILTERED]"}

My controller for omniauth callback like this:

def apple
@user = User.from_omniauth(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: 'apple') if is_navigational_format?
else
session['devise.apple_data'] = request.env['omniauth.auth'].except(:extra)
redirect_to new_user_registation_url
end
end

Help with config values?

Hey y'all, I am writing today to hopefully get some help making sure that I'm using the correct config values in the provider. I'm pretty sure I've got the client, team, and key correct, but I'm curious about the pem: value.

I've seen different versions of a .pem, .p12, and .p8 referenced sort of interchangeably, so, just wanted to make sure that a new .p8 file will work there. Also, should the pem: value be a path the actual file itself, or can it just be the contents of that file as a string?

Thanks for your help!

Can't verify CSRF token authenticity when returning from auth

I am getting 422 Unprocessable Entity errors caused by ActionController::InvalidAuthenticityToken after successful auth redirecting back to the app. I have seen some posts that include the provider_ignores_state: true setting. However, this does not make a difference either (and would potentially cause security issues?).

I am using this as a strategy for Devise, and not directly as Rack middleware, and this is the only auth provider that causes trouble (the other being LinkedIn and Facebook, which work fine).

Is there any reason why this gem would not work as a provider for devise? It seems to be working OK until the redirect step when the CSRF protection causes the problem.

Authentication failure! HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com)

(I'm not sure if this is a duplicate with #76 or a new issue. Even if it is, I cannot make it work with any of the hints in that issue.)

I can successfully authenticate with apple, but then the callback fails with the following error:

2022-11-04T03:42:46.488017+00:00 app[web.1]: E, [2022-11-04T03:42:46.487931 #4] ERROR -- omniauth: (apple) Authentication failure! nonce_mismatch: OmniAuth::Strategies::OAuth2::CallbackError, nonce_mismatch | nonce mismatch
2022-11-04T03:42:46.488850+00:00 app[web.1]: I, [2022-11-04T03:42:46.488804 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] Processing by Users::OmniauthCallbacksController#failure as HTML
2022-11-04T03:42:46.488883+00:00 app[web.1]: I, [2022-11-04T03:42:46.488859 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f]   Parameters: {"state"=>"cd7afa0a1bc11f655a0fe7cd737bb31c68636be05dfe1c86", "code"=>"cec90bc3ac5664ddbbb3d7890c59a8ded.0.rrtrs.wm71iFY5KsYGMy2F1nnW9g"}
2022-11-04T03:42:46.489141+00:00 app[web.1]: W, [2022-11-04T03:42:46.489114 #4]  WARN -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com)
2022-11-04T03:42:46.489474+00:00 app[web.1]: I, [2022-11-04T03:42:46.489445 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 311)
2022-11-04T03:42:46.489572+00:00 app[web.1]: E, [2022-11-04T03:42:46.489547 #4] ERROR -- omniauth: (apple) Authentication failure! HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com): ActionController::InvalidAuthenticityToken, HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com)
2022-11-04T03:42:46.489950+00:00 app[web.1]: I, [2022-11-04T03:42:46.489918 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] Processing by Users::OmniauthCallbacksController#failure as HTML
2022-11-04T03:42:46.489979+00:00 app[web.1]: I, [2022-11-04T03:42:46.489960 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f]   Parameters: {"state"=>"cd7afa0a1bc11f655a0fe7cd737bb31c68636be05dfe1c86", "code"=>"cec90bc3ac5664ddbbb3d7890c59a8ded.0.rrtrs.wm71iFY5KsYGMy2F1nnW9g"}
2022-11-04T03:42:46.490085+00:00 app[web.1]: W, [2022-11-04T03:42:46.490059 #4]  WARN -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com)
2022-11-04T03:42:46.490270+00:00 app[web.1]: I, [2022-11-04T03:42:46.490248 #4]  INFO -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f] Completed 422 Unprocessable Entity in 0ms (ActiveRecord: 0.0ms | Allocations: 140)
2022-11-04T03:42:46.490989+00:00 app[web.1]: F, [2022-11-04T03:42:46.490944 #4] FATAL -- : [b4b4effc-cef6-4567-9509-3d18b9daf37f]
2022-11-04T03:42:46.490989+00:00 app[web.1]: [b4b4effc-cef6-4567-9509-3d18b9daf37f] ActionController::InvalidAuthenticityToken (HTTP Origin header (https://appleid.apple.com) didn't match request.base_url (https://mysite.com)):
2022-11-04T03:42:46.490990+00:00 app[web.1]: [b4b4effc-cef6-4567-9509-3d18b9daf37f]
2022-11-04T03:42:46.490990+00:00 app[web.1]: [b4b4effc-cef6-4567-9509-3d18b9daf37f] actionpack (7.0.4) lib/action_controller/metal/request_forgery_protection.rb:251:in `handle_unverified_request'

I'm on ruby 3.1.2p20 and Rails 7.0.4; using devise, omniauth and omniauth-google-oauth2 successfully.

My callback controller for apple looks like this:

  def apple
    user = User.from_omniauth(auth)

    if user.present?
      sign_out_all_scopes
      flash[:success] = 'Success'
      sign_in_and_redirect user, event: :authentication
    else
      flash[:alert] = 'OAuth failure'
      redirect_to new_user_session_path
    end
  end

Is there a working minimal example app I could check out?

Does not return firstName and lastName

By some reason, for some accounts receive only name in the info object, which equal to email.
AppleId account has firstName and lastName

Any thoughts?

Thanks

Invalid curve name

I continue to get an invalid curve name exception when using what I presume to be a valid key encoded with the ES256 algorithm. Much searching online has not resulted in any explanation as to why this could be happening other than possibly attempting to connect on a staging server.

Here's the error in question:

image

Attempting to validate our connection with the latest omni-auth apple gem using devise.

I followed the steps laid out here to generate the private_key that is failing: https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple#generate-the-client-secret

Can't use Sign In With Apple JS

As far as I can tell, the reason is that omniauth-apple generates a authorize url with response_type=code and Sign in with Apple JS generates one with response_type=code%20id_token. Manually changing the omniauth-apple url in the browser to have the response_type=code%20id_token also fails with the same error.

The error is:

ERROR -- omniauth: (apple) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: 
{"error":"invalid_client"}

So this error seems to be originating somewhere in the omniauth oauth2 implementation: https://github.com/omniauth/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb

Seems like the answer is to support the response_type=code%20id_token thing but I'm not sure how...

https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms

First and last name are nil

Hello. I'm working on an implementation to use this gem with Devise, and everything is working. The problem I'm facing is that, although I'm requesting the user's name, and it shows up as something I'm requesting on the Apple oauth, the name is nil that gets returned from the gem. Is this a known issue? Any fix for it?

ERROR -- omniauth: (apple) Authentication failure! invalid_credentials: OAuth2::Error, invalid_request: {"error":"invalid_request"}

I keep running into the following error in my OmniauthCallbacksController which inherits from Devise::OmniauthCallbacksController. On the front end, I am using the auth-code flow to authenticate users with their Apple ID and then I pass the code and the redirect_uri as body parameters to this devise endpoint. However, I am getting the following error:

ERROR -- omniauth: (apple) Authentication failure! invalid_credentials: OAuth2::Error, invalid_request: {"error":"invalid_request"}

This method works fine with google oauth2, but it's failing for me with Apple.

Perhaps I am missing some configuration or other step, however, I can authenticate with the auth code using the apple_id gem.

Here are some details of my configuration below:

rails version: 7.0.6
devise version: 4.9.2
omniauth-apple version: 1.3.0

devise.rb
`
config.omniauth :google_oauth2, OMNIAUTH_GOOGLE_CLIENT_ID, OMNIAUTH_GOOGLE_CLIENT_SECRET, scope: 'email,profile', provider_ignores_state: true

config.omniauth :apple, OMNIAUTH_APPLE_CLIENT_ID, '', {
scope: 'email name',
team_id: OMNIAUTH_APPLE_TEAM_ID,
key_id: OMNIAUTH_APPLE_KEY_ID,
pem: OMNIAUTH_APPLE_PRIVATE_KEY,
provider_ignores_state: true,
authorized_client_ids: [ OMNIAUTH_APPLE_CLIENT_ID ],
redirect_uri: 'https://lvh.me/login'
}
`

routes.rb
devise_for :users, controllers: { sessions: 'sessions', registrations: 'registrations', omniauth_callbacks: 'users/omniauth_callbacks' }, defaults: { format: :json }

user.rb
devise :database_authenticatable, :confirmable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :jwt_authenticatable, :omniauthable, jwt_revocation_strategy: JwtBlacklist, omniauth_providers: [:apple, :google_oauth2]

Is Ruby 2.1.1 supported by omniauth-apple ?

Hello,

It seems there is a problem with the gem and my config. The app I'm working with is build with Ruby 2.1.1 and Rails 3.2.19 and the following syntax of the apple.rb lib is raising errors:

/Users/denis/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require': /Users/denis/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/omniauth-apple-1.0.0/lib/omniauth/strategies/apple.rb:33: syntax error, unexpected '.' (SyntaxError)
...s['id_token'] || access_token&.params&.dig('id_token')
...                               ^
/Users/denis/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/omniauth-apple-1.0.0/lib/omniauth/strategies/apple.rb:60: syntax error, unexpected '.'
...id_info ||= if request.params&.key?('id_token') || access_to...
...                               ^
/Users/denis/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/omniauth-apple-1.0.0/lib/omniauth/strategies/apple.rb:60: syntax error, unexpected '.'
...?('id_token') || access_token&.params&.key?('id_token')

Thanks for your help.

"stored_nonce" is nil due to different sessions

Hi all,
I would appreciate if I can get some help on the verification of nonce.
During the phase of verify_nonce!, the stored_nonce and the value from payload['nonce'] are different.

I did a bit more debugging, apparently stored_nonce returns nil. It seems like Rails has created a new session, hence new_nonce and stored_nonce are referring to different sessions. Have a look at the byebug output below.

In #new_nonce:

   51:       def new_nonce
   52:         session['omniauth.nonce'] = SecureRandom.urlsafe_base64(16)
   53:         byebug
=> 54:         session['omniauth.nonce']
   55:       end
   56:
   57:       def stored_nonce
   58:         byebug
(byebug) session.id
"7b8a4c453dc2cdceb65aaa861a422284"

In #stored_nonce:

   57:       def stored_nonce
   58:         byebug
=> 59:         session.delete('omniauth.nonce')
   60:       end
   61:
   62:       def id_info
   63:         @id_info ||= if request.params&.key?('id_token') || access_token&.params&.key?('id_token')
(byebug) session.id
"6dec324aa336403ca3e77ae58ee90e8d"
(byebug) session['omniauth.nonce']
nil

The sessions are different, 7b8a4c453dc2cdceb65aaa861a422284 != 6dec324aa336403ca3e77ae58ee90e8d.

Final result: users are logged in, but getting the flash error message:

image

FYI, I am using this gem together with devise.

Wondering whether other people are experiencing the same issue and able to find a solution.
Thanks, looking forward to your replies.

undefined method verify for nil:NilClass in jwt.rb:62:in verify_rsa

I am getting this error: undefined method verify for nil:NilClass in jwt.rb:62:in verify_rsa on the callback. The public_key is nil in the method verify_rsa in the jwt gem.

My config is set up like this:

:apple,
ENV['APPLE_SIGN_IN_CLIENT_ID'], '',
{
  scope: 'email name',
  redirect_uri: ENV['APPLE_SIGN_IN_REDIRECT_URL'],
  pem: File.read(ENV['APPLE_SIGN_IN_PEM_PATH']),
  team_id: ENV['APPLE_SIGN_IN_TEAM_ID'],
  key_id: ENV['APPLE_SIGN_IN_KEY_ID'],
},

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.