We've moved discussions to Discord

Sign in with Apple - now working!

Rob Jonson •
My app will be connected to an iOS app, so if I want any social sign in, then Apple insist I add Sign in with Apple. (annoying but unavoidable)

I have got things working as far as the callback with the following. 

Many edits later, I have things working. I'll leave this as a how-to for the next person...

Setup


#lib/jumpstart/lib/jumpstart/omniauth.rb

add apple to the 

AVAILABLE_PROVIDERS = {
...
,
      "apple" => {
        name: "Apple",
        scope: "email name",
        provider: :apple,
        icon: :apple
      }
    }.freeze

edit has_credentials to not check for private key (apple doesn't provide one)

    def self.has_credentials?(gem_name)
      provider = AVAILABLE_PROVIDERS.dig(gem_name, :provider)
      credentials_for(provider).dig(:public_key).present?
      #apple doesn't have a normal private key
    end

#/app/javascript/stylesheets/components/connected_accounts.scss

.bg-apple { background: #000000; }
.text-apple { color: #000000; }
.btn-apple {
  @apply bg-apple text-white;
}

#in credentials, add details in the format
(instructions here: https://github.com/nhosoya/omniauth-apple/pull/62/files)

  apple:
    public_key: 'app.skydivedesigner.beta'
    private_key: ''
    scope: 'email name'
    team_id: 'MYTEAMID'
    key_id: 'MYKEYID'
    pem: |
      -----BEGIN PRIVATE KEY-----
      real
      contents
      of .p8 file
      you get from apple
      -----END PRIVATE KEY-----


Apple doesn't let you test on localhost, so I set beta.skydivedesigner.app to point to localhost and setup local ssl following instructions here

https://blog.cloud66.com/running-rails-development-with-a-fake-domain-and-ssl/
(nb: command seems to be caddy run now rather than just caddy)

the other change is that it seems the session cookie has to be set to SameSite none.
https://github.com/nhosoya/omniauth-apple/issues/58

I just tweaked the config provided for multidomain

#/config/initializers/session_store.rb
#probably overdoing it a bitRails.application.config.session_store :cookie_store, key: '_jumpstart_session', domain: :all, tld_length: 2, same_site: :none

forgery protection fails, so I disable this for apple (not 100% sure this is a good idea!)

#/app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  skip_forgery_protection only: :apple

and now it works.

so, actually this is all working now (in dev at least...)

thanks

Rob Jonson •
and then it gets weird in production.

one of the steps in the gem is to fetch apple's keys.

I can check that the server can access the info by running

curl https://appleid.apple.com/auth/keys
#correctly returns the keys

however in the gem, it uses 

uri = URI.parse('https://appleid.apple.com/auth/keys')
response = Net::HTTP.get_response(uri)

If I type these into the rails console, then I get a 403 (which is the same as happens for the app)

Can anyone suggest why Net::HTTP.get_response would get a 403 when curl succeeds?

thanks.

Rob Jonson •
additional update - Apple #$$%!
it turns out that from some locations, Apple give a 403 if the useragent for the request is 'Ruby'
My NewYork server gets dinged, My London & Amsterdam servers are fine.
I have added a fix to the oauth_apple gem and sent a pull request.
Adam Howell •
Thanks for laying all this out Rob Jonson ! This is one of my next todos and I was dreading it… 
Hi, thanks putting this together.  I haven't had success, yet.  Any idea why I keep getting the nonce_mismatch?

I'm using the apple button
<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>
<script>
AppleID.auth.init({
  clientId: "app.example",
  scope: "email name",
  redirectURI: "https://my.ngrok.io/users/auth/apple/callback",
  state: "TEST-HEX",
  usePopup: false,
  response_mode: "id_token",
  nonce: "<%= apple_signin_nonce %>",
});
</script>
app/helpers/application_helper.rb
  def apple_signin_nonce
    session["omniauth.nonce"] ||= SecureRandom.urlsafe_base64(16)
    session["omniauth.nonce"]
  end

and receiving this error

web     | Started POST "/users/auth/apple/callback" for 182.253.75.237 at 2022-06-28 10:42:23 +0800
web     | D, [2022-06-28T10:42:23.135569 #67393] DEBUG -- omniauth: (apple) Callback phase initiated.
web     | E, [2022-06-28T10:42:23.970234 #67393] ERROR -- omniauth: (apple) Authentication failure! nonce_mismatch: OmniAuth::Strategies::OAuth2::CallbackError, nonce_mismatch | nonce mismatch
web     | Processing by Users::OmniauthCallbacksController#failure as HTML
web     |   Parameters: {"state"=>"TEST-HEX", "code"=>"...(removed)...", "id_token"=>"...(removed)..."}
web     | Redirected to https://my.ngrok.io/

Any insight would be appreciated! Thanks!

Notifications
You’re not receiving notifications from this thread.