A library for adding Sign In With Apple to Android apps.
This library includes a SignInWithAppleButton
class. You can style the button according to Apple's Human Interface Guidelines.
You can add this button to your login screen. When tapped, the button presents Apple's OAuth login flow in a web view. After the user signs in, your callback will receive an authorization code. You can then pass the authorization code to your backend's third party login endpoint.
You will find this library useful if both of these statements are true:
- Your service has both an Android app and an iOS app.
- Your apps include third-party login, like signing in with Google, Facebook, or Twitter.
In June 2019, Apple announced Sign In with Apple, another third-party login provider. They also announced that if an iOS app offers any third-party login options, it will be an App Store requirement to offer Sign In with Apple. This rule would go into effect "later this year" (2019). That is, if you don't add the feature, at some point you won't be able to ship updates to your iOS app.
Obviously Apple does not control Android. But if you have to add a login method to your iOS app, your users will need it on your Android app too. If it isn't supported, your users won't be able to log in if they switch to Android.
We built this library to make it as painless as possible to add Sign In with Apple to your Android app.
First, follow Apple's instructions to set up Sign In with Apple in your iOS app and for a web service. It is the web service setup that you'll use from Android, but you need both.
More setup is necessary for backend operations, but the above is all you need to use this library. For more detail, you can read Aaron Parecki's walkthrough, What the Heck is Sign In with Apple?
You should have created:
- An App ID
- including the Sign In with Apple capability
- A Service ID
- using the App ID as its primary
- mapped to a domain you control
- which Apple has verified
- including at least one Return URL
From this setup, you will need two OAuth arguments to use this library:
- A client ID, which you entered as the Identifier field of the Service ID.
- A redirect URI, which you entered as the Return URL.
We recommend you use an
https://
address for your redirect URI. If you use anhttp://
address, you may need to include a security configuration to allow cleartext traffic. Although this library should intercept the redirect request, you should regard this as a less secure option. If it's necessary, see the Network security configuration documentation for instructions on setting up a security configuration. Add that file to your Manifest's<application>
tag using the attributeandroid:android:networkSecurityConfig
.
Include as a dependency using Gradle:
repositories {
mavenCentral()
}
dependencies {
implementation 'com.willowtreeapps:signinwithapplebutton:0.3'
}
Snapshot versions are also available.
repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}
dependencies {
implementation 'com.willowtreeapps:signinwithapplebutton:0.4-SNAPSHOT'
}
Add a SignInWithAppleButton
to your login screen's layout.
Configure the button's appearance properties in layout XML:
style
: Specify a style,"@style/SignInWithAppleButton.Black"
(default),"@style/SignInWithAppleButton.White"
, or"@style/SignInWithAppleButton.WhiteOutline"
.sign_in_with_apple_button_textType
: Specify an enum value,"signInWithApple"
(default) or"continueWithApple"
.sign_in_with_apple_button_cornerRadius
: Specify a dimension, like"4dp"
(default),"0dp"
,"8px"
, etc.
These options are based on the style options from Apple's Human Interface Guidelines.
At runtime, create an instance of SignInWithAppleConfiguration
, supplying these values:
clientId
: Use the client ID value from service setup.redirectUri
: Use the redirect URI value from service setup.scope
: Specify a space-delimited string of OpenID scopes, like "name email".
According to our understanding of OpenID Connect, the "openid" scope should be included. But at this time of writing, that causes the authentication page to fail to initialize. Beta idiosyncrasies like these are documented in How Sign in with Apple differs from OpenID Connect.
Configure the button with a FragmentManager
to present the login interface, the service you created above, and a callback to receive the success/failure/cancel result.
Set up a SignInWithAppleButton
via XML:
<com.willowtreeapps.signinwithapplebutton.view.SignInWithAppleButton
android:id="@+id/sign_in_with_apple_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/SignInWithAppleButton.Black"
app:sign_in_with_apple_button_textType="signInWithApple"
app:sign_in_with_apple_button_cornerRadius="4dp" />
In your Activity, create the SignInWithAppleService
, then configure the button:
override fun onCreate(savedInstanceState: Bundle?) {
...
val configuration = SignInWithAppleConfiguration(
clientId = "com.your.client.id.here",
redirectUri = "https://your-redirect-uri.com/callback",
scope = "email"
)
val signInWithAppleButton = findViewById(R.id.sign_in_with_apple_button)
signInWithAppleButton.setUpSignInWithAppleOnClick(supportFragmentManager, configuration) { result ->
when (result) {
is SignInWithAppleResult.Success -> {
// Handle success
}
is SignInWithAppleResult.Failure -> {
// Handle failure
}
is SignInWithAppleResult.Cancel -> {
// Handle user cancel
}
}
}
}
If configuring the button from Java, you can supply an implementation of
SignInWithAppleCallback
instead of a single callback function.
When the user taps the button, it will present a web view configured to let the user authorize your service as an OAuth client of their Apple ID. After the user authorizes access, Apple will forward to the redirect URI and include an authorization code. The web view will intercept this request and locate the authorization code.
If the user completes authentication, your callback will receive a SignInWithAppleResult.Success
with the authorization code. Your backend endpoint can then phone home to Apple to exchange the authorization code for tokens, completing login.
If instead there is a failure, your callback will receive a SignInWithAppleResult.Failure
with the error.
If the user dismisses the authentication screen intentionally, you will receive a SignInWithAppleResult.Cancel
.
If you supplied a
SignInWithAppleCallback
implementation rather than a single callback function, you will instead receive a call to the corresponding callback method.
We've included a sample Android app in the sample
folder. This app is comparable to Apple's sample project for the iOS Sign In with Apple button.
The sample app demonstrates:
- Adding the button and styling it, in
activity_sample.xml
- Configuring the button with service details and a client, in
SampleActivity.onCreate()
orSampleJavaActivity.onCreate()
- Making use of the authorization code on success, in the callback
You can adjust this sample project with your service configuration and try signing in.
SampleActivity
, the Kotlin sample implementation, is launched by the sample app. To viewSampleJavaActivity
, you would need to update the activity name in the sample app's manifest XML.
- Front end components offering a Sign In with Apple button
- Juice, Apple's sample project, as seen in WWDC 2019, Session 706 - Introducing Sign In with Apple
- @react-native-community/apple-authentication, a React Native library
- OmniAuth::Apple, an OmniAuth strategy for Rails web apps
- Backend components for Sign In with Apple
- apple-auth, an NPM package for JavaScript backends
- apple_id, a gem for Ruby backends
- Use a Chrome Custom Tab on Marshmallow and later so users know they are not being phished
- This will require consuming apps to configure App Links, but it's the Right Way to do it for OAuth security
- Keep up with changes to Sign In with Apple during beta; 1.0 when the service itself is 1.0
- Standard Android ripple effect? Material-themed Sign In with Apple button?
Contributions are welcome. Please see the Contributing guidelines.
This project has adopted a code of conduct defined by the Contributor Covenant, the same used by the Swift language and countless other open source software teams.
The Apple logo belongs to Apple. It's included in this library because it's specified in Apple's Human Interface Guidelines. We're using it in good faith according to its intended purpose. As a consumer of this library, please read the HIG and avoid misusing Apple's intellectual property.