Implementing OAuth 2.0 social login with Facebook: A comprehensive guide

Demola Malomo - Jul 28 '23 - - Dev Community

Open Authorization, popularly known as OAuth 2.0, is a secure and fast security mechanism that enables users to access websites and applications. Beyond the safety and ease of use, it gives users total control of the information shared with the requesting websites/applications.

In this post, we will learn how to set up OAuth 2.0 social login in a Flutter application using Facebook 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
  • Facebook developer account; sign-up is completely free

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


Enter fullscreen mode Exit fullscreen mode

Running the project

First, we need to install the project dependencies by running the command below:



flutter pub get


Enter fullscreen mode Exit fullscreen mode

Then, run the project using the following command:

flutter run
Enter fullscreen mode Exit fullscreen mode

The command above will run the application on the selected device.

Login screen

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 as the name, and then click Create.

Create project

Add platform support

To add support for our Flutter app, navigate to the Home menu and click the Flutter App button.

Add platform

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.

Select new Flutter app

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.

Change deployment target

Enable Facebook as the preferred OAuth 2.0 provider

To do this, we need to navigate to the Auth menu, click the Settings tab, and enable Facebook as a provider.

Navigate to the provider
Facebook OAuth

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 Facebook.

Copy URI

Set up Facebook OAuth 2.0

With our project partly configured on Appwrite, we also need to set up our project on the Facebook developer portal. To do this, log into the portal, navigate to the My Apps section, click the Create App button, select the Set up Facebook Login option and click Next.

Create App
Select option

Next, we need to input our application name, contact email, and then select Create app.

Create

Finally, we navigate to the Products menu, select Settings under Facebook Login, input the redirect URI we copied from Appwrite earlier, and Save changes.

Settings
URI

Lastly, we need to click on the Products menu again, select the QuickStart option, and select iOS as the preferred platform.

Quickstart
iOS app

Configuring the iOS

After selecting the iOS option, click the Next button, input the Bundle ID, Save, and Continue.

Step 1
Step 2

Click Next on the Enable Single Sign On for Your App step.

Enable Single Sign On for Your App

Next, we need to copy and configure our Application using the provided XML snippet.

Copy the provided XML snippet

To do this, we need to modify the info.plist file in our source code and paste the copied snippet below the <dict> body tag.

We can find the file using the path below:
ios > Runner > info.plist

Snippet

We must also update the snippet with our Application ID, Client Token, and App name.

We can get the required parameter as shown below:

Application ID
Client Token

Sample of a properly filled snippet below:



<key>CFBundleURLTypes</key>
<array>
<dict>
<key>1232334554343456</key>
<array>
    <string>1232334554343456</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>APP-ID</string>
<key></key>
<string>1ac7fd263ettr6yeta1b807ad589rt</string>
<key>flutter_auth</key>
<string>APP-NAME</string>


Enter fullscreen mode Exit fullscreen mode

Putting it together on Appwrite

With our application configured on Facebook, we need to create a link to it on Appwrite. To do this, we need to first navigate to the Basic tab under Settings menu and copy the App ID and App secret.

App ID And App secret

Lastly, we need to update the Facebook provider details on Appwrite with the copied parameters and Update.

Add App ID an App Secret

Integrating Facebook 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";
}


Enter fullscreen mode Exit fullscreen mode

PS: We can get our Project ID from the Appwrite console.

Second, 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/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 loginWithFacebook() async {
    try {
      return await _account.createOAuth2Session(provider: 'facebook');
    } catch (e) {
      throw Exception('Error login into Facebook!');
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

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 loginWithFacebook method that uses the _account property to login with OAuth 2.0 using facebook 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/auth_service.dart';

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  bool _isLoading = false;

  _loginWithFacebook() {
    setState(() {
      _isLoading = true;
    });
    AuthService()
        .loginWithFacebook()
        .then((value) => {
              setState(() {
                _isLoading = false;
              })
            })
        .catchError((e) {
      setState(() {
        _isLoading = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Error login into facebook!')),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Image.asset('images/lock.png'),
            const SizedBox(height: 40.0),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: Container(
                width: double.infinity,
                height: 45.0,
                child: TextButton(
                  onPressed: _isLoading
                      ? null
                      : () {
                          _loginWithFacebook();
                        },
                  child: Text(
                    'Login with Facebook',
                    style: TextStyle(
                        fontSize: 12.0,
                        fontWeight: FontWeight.bold,
                        color: Colors.white),
                  ),
                  style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all(Color(0xff3b5998)),
                      padding: MaterialStateProperty.all<EdgeInsets>(
                        const EdgeInsets.symmetric(horizontal: 15.0),
                      )),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

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 _loginWithFacebook method to log in users using the AuthService().loginWithFacebook service and set state accordingly
  • Lines 52-56: 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


Enter fullscreen mode Exit fullscreen mode

Facebook update on business verification

Facebook recently updated its permission system for applications using OAuth 2.0. It requires the developer to do a Business Verification to gain full access. If we decide to log in using our credentials, we will get an error about permissions, as shown below:

Permission issue

Conclusion

This post detailed a step-by-step guide to implementing Facebook OAuth 2.0 social login in a Flutter application using Appwrite. Beyond Facebook, Appwrite supports up to 35 other providers.

These resources may also be helpful:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .