Apple’s iOS is one of the leading mobile operating systems, with an estimated market share of about 20.5% of the global smartphone market. Beyond its usability, timely updates, security, and privacy features, an integral part of the system is the Apple ID; an identifier for accessing all Apple products and services.
In 2019, Apple announced the Sign in with Apple functionality. A fast, secure, and easy way for users to sign in to applications and websites. The functionality has helped developers seamlessly build software without the associated authentication and authorization overheads.
In this post, we will learn how to set up OAuth 2.0 social login in a Flutter application using Apple as the provider. The project repository can be found here.
Prerequisites
To fully grasp the concepts presented in this tutorial, the following are required:
- Basic understanding of Dart and Flutter
- Flutter SDK installed
- Xcode with a developer account
- Appwrite account; sign-up is completely free
- Apple developer account
Getting started
To get started, we need to clone the project by navigating to the desired directory and running the command below:
git clone https://github.com/Mr-Malomz/flutter_auth_apple
Running the project
First, we need to install the project dependencies by running the command below:
flutter pub get
Then, run the project using the following command:
flutter run
The command above will run the application on the selected device.
Set up a project on Appwrite
To get started, we need to log into our Appwrite console, click the Create project button, input flutter_auth_apple
as the name, and then Create.
Add platform support
To add support for our Flutter app, navigate to the Home menu and click the Flutter App button.
Next, we must modify the Flutter application as detailed below:
To obtain our Bundle ID, navigate to the path below:
ios > Runner.xcodeproj > project.pbxproj
Open the project.pbxproj
file and search for PRODUCT_BUNDLE_IDENTIFIER
.
Finally, open the project directory on Xcode, open the Runner.xcworkspace
folder in the app's iOS folder, select the Runner project in the Xcode project navigator, select the Runner target in the primary menu sidebar, and then select iOS 11 in the deployment info’s target.
Enable Apple as the preferred OAuth 2.0 provider
To do this, we must navigate to the Auth menu, click the Settings tab, and enable Apple
as a provider.
We will fill in the required details later. However, we must copy and keep the redirect URI, it will come in handy when setting up our application on the Apple developer portal.
Set up Apple OAuth 2.0
With our project partly configured on Appwrite, we must also set up our project on the Apple developer portal.
Create App ID using Xcode
An App ID is used to identify one or more applications in the development team. We must tie our application with an App ID on the platform. To get started, we need to first open the ios
folder in our source code with Xcode.
Second, we must add Sign in with Apple capability to our App ID. To do this, navigate to the Signing & Capabilities tab, click the “+ Capability” button, search for Sign in with Apple
, and double-click the result to add it.
Lastly, we must modify our Bundle Identifier to a unique string by prefixing it with any letters of our choice and then change the Team to our Apple developer team.
On doing the step above, the system should automatically create an App ID for us. See details below.
PS: We might get an error about registering the bundle identifier; we can resolve this by prefixing the Bundle identifier to another set of unique strings. Beyond the use of Xcode, we can also create an App ID using our Apple developer portal.
Create a Service ID
A Service ID is used to identify the applications or websites interacting with Apple web services. To do this, we need to log into the portal, navigate to the Identifiers screen, change to Services IDs, and Register a Services ID.
https://developer.apple.com/account/resources/identifiers/list/serviceId
Select Service IDs and Continue.
Input flutter auth apple
as the Description, input another unique ID as the Identifier, and Register. We also need to keep the inputted Identifier as it will come in handy when we finish setting up our application on Appwrite.
View the details of the newly created Service ID, enable the Sign in with Apple
and Configure.
Select the App ID we configured using Xcode earlier, input appwrite.io
as the Domain, input the Redirect URI we copied from Appwrite earlier as the Redirect URLs, click Next, and Save.
Create a Key ID
We need to create a key ID that our application will use to securely communicate with Apple services. To do this, navigate to the Keys tab and Create.
Input flutterAuthApple
as the Key Name, enable the Sign in with Apple
option, and Configure.
Select the App ID we created earlier and Save.
Register the key, copy the Key ID, and Download the Key File
.
Putting it together on Appwrite
With our application configured on Apple, we need to create a link to it on Appwrite. To do this, we must update the Apple provider details on Appwrite with the copied Service ID Identifier, Key ID, Team ID, P8 File, and Update.
We can get our Team ID by navigating to the Membership details
of the Apple Developer account section and the P8 File by opening the downloaded Key File
in an editor.
Integrating Apple OAuth 2.0 with Flutter using Appwrite
With all that done, let’s build the social login into our application. First, we need to create a class for storing our Appwrite credentials. To do this, we need to create a utils.dart
file in the lib
folder and add the snippet below:
class AppConstant {
final String projectId = "REPLACE WITH PROJECT ID";
final String endpoint = "https://cloud.appwrite.io/v1";
}
PS: We can get our Project ID from the Appwrite console.
Secondly, we need to create a service file to separate the application core logic from the UI. To do this, we need to create an auth_service.dart
file in the same lib
folder and add the snippet below:
import 'package:appwrite/appwrite.dart';
import 'package:flutter_auth_apple/utils.dart';
class AuthService {
Client _client = Client();
late Account _account;
AuthService() {
_init();
}
//initialize the application
_init() async {
_client
.setEndpoint(AppConstant().endpoint)
.setProject(AppConstant().projectId);
_account = Account(_client);
}
Future loginWithApple() async {
try {
return await _account.createOAuth2Session(provider: 'apple');
} catch (e) {
throw Exception('Error login into Apple!');
}
}
}
The snippet above does the following:
- Imports the required dependencies
- Creates an
AuthService
class with_client
and_account
properties to connect to the Appwrite instance - Creates an
_init
method that configures Appwrite using the properties - Creates a
loginWithApple
method that uses the_account
property to log in with OAuth 2.0 usingapple
as the provider
Lastly, we need to modify the login.dart
file inside the screens
folder to use the service.
import 'package:flutter/material.dart';
import 'package:flutter_auth_apple/auth_service.dart';
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
bool _isLoading = false;
_loginWithApple() {
setState(() {
_isLoading = true;
});
AuthService()
.loginWithApple()
.then((value) => {
setState(() {
_isLoading = false;
})
})
.catchError((e) {
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Error login into Apple!')),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Appwrite + Apple Auth",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
const SizedBox(height: 30),
SizedBox(
width: double.infinity,
height: 45.0,
child: TextButton(
onPressed: _isLoading
? null
: () {
_loginWithApple();
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.black),
),
child: const Text(
'Sign in with Apple',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0,
),
),
),
),
],
),
),
);
}
}
The snippet above does the following:
- Lines 1-2: Import the required dependencies
- Line 12: Creates an
_isLoading
property to manage the application state - Lines 14-33: Create a
_loginWithApple
method to log in users using theAuthService().loginWithApple
service and set state accordingly - Lines 57-61: Update the button to use the method created
With that done, we restart the application using the code editor or run the command below:
flutter run
Conclusion
This post detailed a step-by-step guide on how to add Apple OAuth 2.0 social login in a Flutter application using Appwrite. Beyond what was discussed above, the SDK also supports the success
, failure
, and scope
mechanism
for managing callbacks and the amount of user information requested from Apple.
These resources may also be helpful: