Implementing OAuth2 Clients with Flutter made simple
Table of contents
Having to input our information every time we register for a new service is tiring. With open authorization or OAuth2, we no longer have to undergo that pain. Open authorization is a design that lets websites and applications access certain hosted resources from a provider by request from the user. These resources can range from the user’s registered email address to personal information to cloud data.
This article will show how to implement OAuth2 in a Flutter application with Google as the provider and Appwrite as the OAuth2 Client. Here is the link to the repository containing the code for this project.
Prerequisites
The following are required to follow along with this tutorial:
- Basic understanding of Dart and Flutter
- Flutter SDK installed
- Xcode with a developer account
- Appwrite account; sign-up is completely free
- A Gmail account; sign-up is completely free
Creating an Appwrite project
After registering on the Appwrite cloud platform, we will be redirected to an onboarding page where we will have to create a new project. We will fill in our preferred project name and ID (optional as ID can be autogenerated), then select Create Project.
After creating a new project, we must register our application to a specific platform within our project. Therefore, in the Add platform area of the Home section, we will select the Flutter App
button and select our preferred operating system (in this case, Android
). Then, we will fill in the application and package names (the package name is in the app-level build.gradle
file).
Getting started
We will start by cloning the project repository to our PC. This repository contains the template and code we will use for the project. To clone the repository, run the command below:
git clone https://github.com/muyiwexy/google_auth_flutter.git
After the cloning process, we will run the command flutter pub get
to load all the packages used in the project to our PC.
Finally, we will run the project using the command flutter run
and we should have the result below:
To use our Appwrite instance within our Flutter app, we need to connect our project to Appwrite. This process differs from the emulator's OS (Android or IOS).
iOS
First, obtain the bundle ID
by going to the project.pbxproj
file (ios > Runner.xcodeproj > project.pbxproj
) and searching for the PRODUCT_BUNDLE_IDENTIFIER
.
Now, head to the Runner.xcworkspace
folder in the applications iOS folder in the project directory on Xcode. To select the runner target, choose the Runner project in the Xcode project navigator and find the Runner target
. Then, select General and IOS 11.0
in the deployment info section as the target.
Android
For Android, copy the XML script below and paste it below the activity tag in the Androidmanifest.xml
file (to find this file, head to android > app > src > main
).
{% embed gist.github.com/muyiwexy/f1a0f6c59329d25d37.. %}
Note: change [PROJECT-ID] to the ID used when creating the Appwrite project.
Enabling Google OAuth2 provider In order to use Google as a provider in Appwrite, we will need to have it enabled. To do this, we will head to Auth > Settings. We will scroll to Google and check the enabled switch within the settings area. We are also required to fill in the App ID and secret, but we will do that later as we initially need to set up Google OAuth.
Setting up Google OAuth 2.0 To set up, we will head to the Google API console page and head to API and Services within our project (we must create a new project if we do not have one).
Next, we select Credentials, followed by clicking on CREATE CREDENTIALS. Doing this will show a dropdown with some options, and we will proceed to select OAuth client ID.
Note: If it is your first time creating a client ID, you will need to configure your consent screen, which you won’t be required to do again after.
When creating a new OAuth Client ID, we will follow the configurations below:
- Application Type -
Web Application
- Name - (choose preferred name)
- Authorized JavaScript origins
- URIs1 - cloud.appwrite.io
- URIs2 - localhost
- Authorized redirect URIs
- URIs - paste URL from the Google OAuth provider provided by Appwrite
After filling in the prompts on the page, we select save. Then we will get a splash screen showing our client ID and secret.
We will then head back to the Google OAuth provider page, paste in the Client ID and secret in the App ID and secret section, respectively, and click update. That is all, and we have successfully enabled Appwrite as our OAuth2 client.
Google OAuth2 provider and Flutter
This project utilizes the provider
package for its state management. In the util.dart
file, we will create an Appconstants
class to serve as placeholders for some important constants, such as our Appwrite endpoint and ProjectID. Next, create a ChangeNotifier
class called AppProvider. This class initializes the client and account instance from Appwrite. Next, create a function called socialSignIn
which takes in the OAuth2 provider
as a string and context. This function will use the Account API to create a new OAuth2 session on Appwrite and run the condition that if an account is successfully created, it redirects to a new page by setting _isLoggedin
to true
.
import 'package:appwrite/appwrite.dart';
import 'package:flutter/material.dart';
import 'package:google_auth/screens/home.dart';
class Appconstants {
static const String endpoint = "<endpoint or hostname>";
static const String projectid = "<project ID>";
}
class AppProvider extends ChangeNotifier {
Client client = Client();
late Account account;
late bool _isLoggedIn;
bool get isLoggedIn => _isLoggedIn;
AppProvider() {
_isLoggedIn = true;
initialize();
}
initialize() {
client
..setProject(Appconstants.projectid)
..setEndpoint(Appconstants.endpoint);
account = Account(client);
checkLogin();
}
checkLogin() async {
try {
await account.get();
} catch (_) {
_isLoggedIn = false;
notifyListeners();
}
}
socialSignIn(String provider, context) async {
await account
.createOAuth2Session(
provider: provider,
success: "",
failure: "",
)
.then((response) {
_isLoggedIn = true;
notifyListeners();
}).catchError((e) {
_isLoggedIn = false;
notifyListeners();
});
}
}
To use this code from our ChangeNotifier
class, we will create a UI consisting of a button and an alternate screen called Homepage
, which we will route to after successfully running the socialSignIn
function. Therefore, in our lib
folder, create an alternate folder called screens
and create two files in it, user_reg.dart
and home.dart
.
The user_reg.dart
screen’s UI will contain an elevated button in which its onPressed
property triggers the socialSignIn
function in the ChangeNotifier
class.
import 'package:flutter/material.dart';
import 'package:google_auth/util.dart';
import 'package:provider/provider.dart';
class UserRegistration extends StatefulWidget {
const UserRegistration({super.key, required this.title});
final String title;
@override
State<UserRegistration> createState() => _UserRegistrationState();
}
class _UserRegistrationState extends State<UserRegistration> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: IntrinsicWidth(
child: Container(
padding: const EdgeInsets.all(20.0),
decoration: const BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
child: ElevatedButton.icon(
onPressed: () {
final state = Provider.of<AppProvider>(context, listen: false);
state.socialSignIn("google", context);
},
icon: const Icon(Icons.g_mobiledata),
label: const Text("Sign in with Google"),
),
),
),
),
);
}
}
For the home.dart
file, we will have a StatefulWidget
called Homepage consisting of text at the center of the page.
import 'package:flutter/material.dart';
class Homepage extends StatefulWidget {
const Homepage({super.key});
@override
State<Homepage> createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: Text("data"),
),
);
}
}
When we run the app, we should have our results as below:
Conclusion
This post showed how to use Google as a provider using Appwrite as an OAuth client. Appwrite utilizes Google as a provider and serves as a client for 35 more providers. Thus, creating a vast plain of knowledge to explore.
Here are some resources to aid the learning journey: