Integrating UAE PASS into a Flutter application
UAE PASS is a digital identity platform provided by the government of the United Arab Emirates, enabling users to access various government services securely.
Before we dive in, let’s understand what is a UAE PASS. UAE PASS is a foundational platform to accelerate the transformation towards a digital-based economy and digital society. This platform enables UAE PASS users to register and authenticate themselves in a system integrated with SPs (Service Providers) across the UAE.
By using my package flutter_uae_pass
Prerequisites
- UAE PASS account as a developer (send a request to the government to provide main information like name, callback URL, …)
- ClientID
- ClientSecret
Testing Credentials
The below credentials can be used to test authentication & signing services offered by UAE Pass on the Staging environment.
clientId: sandbox_stage
clientSecret: sandbox_stage
The credentials will only work in the staging environment and should not be used in the production environment. For the production environment, you need to contact the UAE PASS and obtain the production credentials.
Getting Started
- Add the plugin to your pubspec.yaml file
flutter_uae_pass: ^0.0.1
- Run flutter pub get
flutter pub get
- Import the package
import 'package:flutter_uae_pass/uae_pass.dart';
final _uaePassPlugin = UaePass();
- Initialize the plugin — Sandbox
await _uaePassPlugin.setUpSandbox();
- Initialize the plugin — Production
await _uaePassPlugin.setUpEnvironment(
clientId: "<clientId>",
clientSecret: "<clientSecret>",
urlScheme: "myappscheme",
redirectUri: "<redirectUri>",
isProduction: true,
);
Scopes are as follows
- urn:uae:digitalid:profile:general
- urn:uae:digitalid:profile
Android Setup
- Update android:launchMode=”singleTask” the AndroidManifest.xml file
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask"
.....
</activity>
- Set up the queries in your AndroidManifest.xml file (To make our app open UAE Pass App)
<queries>
<package android:name="ae.uaepass.mainapp" />
<package android:name="ae.uaepass.mainapp.qa" />
<package android:name="ae.uaepass.mainapp.stg" />
</queries>
- Set up the intent filter in your AndroidManifest.xml file (To Reopen our application after uaepass is done)
<intent-filter >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="success"
android:scheme="myappscheme" />
<data
android:host="failure"
android:scheme="myappscheme" />
</intent-filter>
iOS Setup
- Add the following to your Info.plist file
<key>LSApplicationQueriesSchemes</key>
<array>
<string>uaepass</string>
<string>uaepassqa</string>
<string>uaepassdev</string>
<string>uaepassstg</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>myappscheme</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myappscheme</string>
</array>
</dict>
</array>
“ Make sure to use your own app scheme instead of myappscheme:// in both Staging and Production environments in order to avoid app redirection issues from your app to other service provider apps.”
Main features
- signIn()
- getAccessToken(String authCode)
- getProfile(String token)
- signOut()
Call the authenticate method
String? authCode = await _uaePassPlugin.signIn();
To get access token
String? accessToken = await _uaePassPlugin.getAccessToken(authCode);
To get public profile data
ProfileData? profileData = await _uaePassPlugin.getProfile(accessToken);
Demo
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_uae_pass/uae_pass.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? authCode;
String? accessToken;
ProfileData? profileData;
final _uaePass = UaePass();
@override
void initState() {
super.initState();
_uaePass.setUpEnvironment(
clientId: "<clientId>",
clientSecret: "<clientSecret>",
urlScheme: "myappscheme",
redirectUri: "<redirectUri>",
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('UAE Pass'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MaterialButton(
onPressed: () => login(),
child: const Text('Sign in with UAE Pass'),
),
const SizedBox(height: 100),
if (authCode != null)
ListTile(
title: const Text('Auth Code'),
subtitle: Text('${authCode?.substring(0, 6)}............'),
),
if (accessToken != null)
ListTile(
title: const Text('Access Token'),
subtitle: Text('${accessToken?.substring(0, 6)}............'),
),
if (profileData != null)
Column(
children: [
ListTile(
title: const Text('Full Name EN'),
subtitle: Text(profileData?.fullnameEN ?? ""),
),
ListTile(
title: const Text('Mobile'),
subtitle: Text(profileData?.mobile ?? ""),
),
ListTile(
title: const Text('Nationality EN'),
subtitle: Text(profileData?.nationalityEN ?? ""),
),
],
),
],
),
),
),
);
}
Future<void> login() async {
authCode = null;
accessToken = null;
profileData = null;
setState(() {});
try {
authCode = await _uaePass.signIn();
accessToken = await _uaePass.getAccessToken(authCode ?? "");
profileData = await _uaePass.getProfile(accessToken ?? "");
setState(() {});
} catch (e) {
if (kDebugMode) {
print(e.toString());
}
}
setState(() {});
}
}
Source Code for example