Add Infisign Widget to Flutter App and Manage Authentication

This shows how to add the Infisign widget to your Flutter App and Manage Authentication

Setting Up WebView Flutter Plus

Add Dependency

Include the webview_flutter_plus package in your pubspec.yaml file:

dependencies:
  webview_flutter_plus: ^0.4.5

Install the package via command line:

flutter packages get

Android Setup

  1. Add android:usesCleartextTraffic="true" in AndroidManifest.xml under the application tag:
<application android:usesCleartextTraffic="true">
</application>
  1. Add necessary permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

iOS Setup

Add the following in your Info.plist :

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>
<key>io.flutter.embedded_views_preview</key>
<true/>

UniFed Widget HTML

Place the HTML file in asset/html :

<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
    <script src="https://infisign-fe-images.s3.amazonaws.com/infisign-auth-widget/polyfills.js" type="module"></script>
    <script src="https://infisign-fe-images.s3.amazonaws.com/infisign-auth-widget/main.js" type="module"></script>
    <link rel="stylesheet" href="https://infisign-fe-images.s3.amazonaws.com/infisign-auth-widget/styles.css" media="print" onload="this.media='all'">
  </head>
  <body>
    <infisign-auth widgetid="acme-6655a72c2f514699e6d8395f-Dev"></infisign-auth>
  </body>
</html>

Add the assets in pubspec.yaml :

- asset/html/

widget.dart Implementation

Create a Dart file for the widget:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:webview_flutter_plus/webview_flutter_plus.dart';

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

  @override
  State<NewAuthWidgetScreen> createState() => _NewAuthWidgetScreenState();
}

class _NewAuthWidgetScreenState extends State<NewAuthWidgetScreen> {
  late WebViewControllerPlus _controller;
  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    _controller = WebViewControllerPlus()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(NavigationDelegate(
        onUrlChange: (change) {
          if (change.url!.contains("infisignplay://")) {
            Navigator.pop(context, change.url);
          }
        },
        onPageStarted: (url) {
          setState(() {
            isLoading = false;
          });
        },
      ))
      ..loadFlutterAsset('asset/html/index.html');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: const Color(0xff01255f),
        leading: IconButton(
          icon: SvgPicture.asset('assets/icons/arrow_left.svg', color: Colors.white),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        title: Text('App Logo', style: TextStyle(color: Colors.white)),
        centerTitle: true,
        automaticallyImplyLeading: false,
      ),
      body: isLoading
          ? Center(child: CupertinoActivityIndicator())
          : WebViewWidget(controller: _controller),
    );
  }

  @override
  void dispose() {
    _controller.server.close();
    super.dispose();
  }
}

Authentication Handling

This flow demonstrates the steps to create an authentication token and then use that token to fetch user profile information securely.


Once you get the redirect URL from the widget, you can retrieve the secret key using the sample data from the redirect URI:


1. Create Token [POST] Request

Request:

This step involves sending a POST request to create an authentication token.

// Encoding credentials
final username = unifeduserkey;
final password = unifedsecretkey;
final credentials = base64Encode(utf8.encode('$username:$password'));

var headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Basic $credentials',
};

// Constructing the POST request
var request = http.Request(
  'POST', 
  Uri.parse('https://unifed-dev-api.infisign.net/unifed-auth-service/unifed$tenant_id/magic/auth/create/token/')
);
request.body = json.encode({
  "code": "code", // Obtained from redirect URL
  "secret_key": "SECRET KEY from previous API"
});
request.headers.addAll(headers);
Response:

On successful token creation, the response returns an access token, refresh token, token type, and expiry information.


{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTY4OTM0NzcsImlhdCI6MTcxNjgwNzA3Nywic3RhdGUiOiJlZWMwMDkxMy02ZjY5LTRiNTEtYTE0Zi0xOWJiZTVhNjZlYjciLCJ1c2VyX2lkIjoiNjYzYjY4Y2FjNTUxYWJmYTIyNjg0YTM4IiwiZW1haWxfaWQiOiJqZWJhc3RpbkBlbnRyYW5zLmlvIiwidXNlcl9uYW1lIjoiSmViYXN0aW4gRyIsInR5cGUiOiJtYWdpYyIsInVzZXJfdHlwZSI6ImRpcmVjdCJ9.E0QnziPTRvQQzK4Y9tF7RiP3d61qv9Pq0WxKxINE-UE",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTY4OTM1OTcsImlhdCI6MTcxNjgwNzA3Nywic3RhdGUiOiJlZWMwMDkxMy02ZjY5LTRiNTEtYTE0Zi0xOWJiZTVhNjZlYjciLCJ1c2VyX2lkIjoiNjYzYjY4Y2FjNTUxYWJmYTIyNjg0YTM4IiwiZW1haWxfaWQiOiJqZWJhc3RpbkBlbnRyYW5zLmlvIiwidXNlcl9uYW1lIjoiSmViYXN0aW4gRyIsInR5cGUiOiJtYWdpYyIsInVzZXJfdHlwZSI6ImRpcmVjdCJ9.-yCgoR6ii46rfMmA1ynsKMxMeLPY5cT5ECFatkY_XK0",
"token_type": "bearer",
"expires_in": 86400
}

2. Get Profile [GET] Request

Request:

This step involves sending a GET request to fetch the user's profile using the previously obtained credentials.


// Encoding credentials
final username = unifeduserkey;
final password = unifedsecretkey;
final credentials = base64Encode(utf8.encode('$username:$password'));

var headers = {
'Authorization': 'Basic $credentials',
};

// Constructing the GET request
var request = http.Request(
'GET', 
Uri.parse('https://unifed-dev-api.infisign.net/unifed-auth-service/unifed$tenant_id/magic/auth/user/profile/')
);
request.headers.addAll(headers);
Response:

On successfully fetching the profile, the response contains user details such as email, mobile number, name, and other profile information.

{
"status": "success",
"message": "User Profile fetched successfully",
"data": {
"secondaryEmailIds": "",
"mobileNumber": "*7147",
"countryCode": "+91",
"emailId": "@infisign.io",
"givenName": "****",
"Logo": "",
"DOJ": "14-09-2020",
"DOB": "1991-07-03",
"statusUpdated": "2024-05-27T12:39:19.934000"
}
}

Still need help? Contact Us Contact Us