-
-
Notifications
You must be signed in to change notification settings - Fork 23
Client
Nov Matake edited this page Jul 12, 2022
·
10 revisions
Use this class to obtain Access Token & ID Token.
You need to register OAuth Client at Apple Developer Site.
Basically, you need
- Register an App ID with "Sign in with Apple" capability
- Register a Service ID with Primary App ID set as the above App ID
- Verify your
REDIRECT_URI
domain by uploading/.well-known/apple-developer-domain-association.txt
to your server - Register a Key for the Primary App ID
During registration, you can get
-
CLIENT_ID
a.k.a. "Service ID" -
KEY_ID
which is displayed at the key details page
For more details, read this official document.
private_key_pem = <<-PEM
-----BEGIN PRIVATE KEY-----
:
-----END PRIVATE KEY-----
PEM
client = AppleID::Client.new(
identifier: CLIENT_ID,
team_id: TEAM_ID,
key_id: KEY_ID,
redirect_uri: REDIRECT_URI,
private_key: OpenSSL::PKey::EC.new(private_key_pem)
)
session[:state] = SecureRandom.hex(16)
session[:nonce] = SecureRandom.hex(16)
authorization_uri = client.authorization_uri(
state: session[:state],
nonce: session[:nonce],
scope: [:email, :name],
response_mode: :form_post
)
redirect_to authorization_uri
Confirm params[:state]
is the same value with session[:state]
which you generated at sending Authorization Request.
If those are different, it's CSRF attack.
unless params[:state] == session[:state]
raise 'CSRF Attack Detected'
end
Once you get params[:code]
, you can exchange it with OAuth Access Token & ID Token.
if params[:code].present?
client.authorization_code = params[:code]
token_response = client.access_token!
token_response # => AppleID::AccessToken
token_response.access_token # => String
token_response.refresh_token # => String
token_response.id_token # => AppleID::IdToken
end
See AppleID::AccessToken and AppleID::IdToken for details.
User rejected to sign-in, or some other reason.
if params[:error]
raise "OAuth Error: #{params[:error]} #{params[:error_description]}"
end
client.refresh_token = "<existing-refresh-token>"
token_response = client.access_token!
token_response # => AppleID::AccessToken
token_response.access_token # => String
# NOTE: Apple issues no refresh_token nor id_token when refreshing access token
token_response.refresh_token # => nil
token_response.id_token # => nil
client.revoke!(access_token: '<existing-access-token>')
client.revoke!(refresh_token: '<existing-refresh-token>')
or
client.refresh_token = '<existing-refresh-token>'
client.revoke!