flutter_cookie_bridge 1.3.1
flutter_cookie_bridge: ^1.3.1 copied to clipboard
A Flutter plugin that synchronizes cookies between network requests and WebViews.
example/lib/main.dart
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cookie_bridge/web_view_callback.dart';
import 'package:flutter_cookie_bridge/network_manager.dart';
import 'package:flutter_cookie_bridge/flutter_cookie_bridge.dart';
import 'package:flutter_cookie_bridge_example/DeviceInfoManager.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:package_info_plus/package_info_plus.dart';
final cookieBridge = FlutterCookieBridge();
void main() async {
await dotenv.load(fileName: "lib/.env");
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: MyHome());
}
}
class MyHome extends StatefulWidget {
const MyHome({super.key});
@override
MyHomeState createState() => MyHomeState();
}
class MyHomeState extends State<MyHome> {
final String? baseUrl = dotenv.env['BASE_URL'];
// Your controller
final TextEditingController prospectIDcontrolller = TextEditingController();
@override
void dispose() {
prospectIDcontrolller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Login')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: prospectIDcontrolller,
textInputAction: TextInputAction.done,
decoration: const InputDecoration(
labelText: "Prospect ID",
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
final id = prospectIDcontrolller.text.trim();
if (id.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Please enter Prospect ID")),
);
return;
}
_openWebView1(context,id);
},
child: const Text('Login'),
),
),
],
),
),
),
),
);
}
}
Future<String> createToken() async {
final String clientId = dotenv.env['KID']!;
final Map<String, Object> headers = {
'kid': clientId,
'typ': 'JWT',
'alg': 'HS256',
};
final Map<String, String> attributes = {
'name': "name",
'photo': "",
};
const Duration expirationDuration = Duration(milliseconds: 300000);
final clientSecret = dotenv.env['CLIENT_SECRET'];
final jwt = JWT(
{
'email': "email",
'phone': "phone",
'attributes': attributes,
'module': "module",
},
header: headers,
);
String token = await jwt.sign(
SecretKey(clientSecret!),
expiresIn: expirationDuration,
);
print("Token generated FROM client side is: $token");
return token;
}
Future<void> open(BuildContext context, String module, String token,
WebViewCallbackFunction? callback) async {
try {
String bank = "";
if (module.contains("banking/")) {
int startIndex = module.indexOf("banking/") + "banking/".length;
String temp = module.substring(startIndex);
int endIndex = temp.indexOf("/");
bank = endIndex == -1 ? temp : temp.substring(0, endIndex);
}
// await _loginAndNavigateToWebView(module, bank, context, token, callback!);
} catch (e) {
debugPrint('Error opening webview: $e');
rethrow;
}
}
// Future<void> _loginAndNavigateToWebView(
// String module,
// String bank,
// BuildContext context,
// String token,
// WebViewCallbackFunction callback,
// ) async {
// try {
// await cookieBridge.clearSession();
// final tokenResponse = await _networkManager.request(
// url: "tokenUrl",
// method: 'POST',
// body: {"token": token});
//
// print("token Response is: $tokenResponse");
//
// if (tokenResponse?.statusCode == 200 &&
// tokenResponse?.data['code'] == "USER_LOGIN_SUCCESS") {
// final cookies = await cookieBridge.checkSession();
//
// if (cookies.isEmpty) {
// throw Exception('Session not established after login');
// }
//
// await _checkDeviceBinding(context, bank, module, callback);
// } else {
// debugPrint('Error during login: $tokenResponse');
// // rethrow;
// }
// } catch (e) {
// debugPrint('Unexpected error: $e');
// rethrow;
// }
// }
Future<void> _checkDeviceBinding(BuildContext context, String bank,
String url, WebViewCallbackFunction callback) async {
// if (LibraryConstants.deviceBindingEnabled) {
// // TODO Build the device binding flow
// } else {
//Skip device binding and bind device to session
// await _setupDeviceSession(context, bank, url, callback);
// }
}
// Future<void> _setupDeviceSession(BuildContext context, String bank,
// String url, WebViewCallbackFunction callback) async {
// try {
// Map<String, String> deviceInfo = await _deviceInfoManager.getDeviceInfo();
// final packageInfo = await PackageInfo.fromPlatform();
// if (kDebugMode) {
// print("Device Info: $deviceInfo");
// print("Package Info: $packageInfo");
// }
// final bindDeviceToSessionResponse = await _networkManager.request(
// url:
// "sessionUrl",
// method: 'POST',
// body: {
// "manufacturer": deviceInfo["manufacturer"]!,
// "model": deviceInfo["model"]!,
// "device_uuid": deviceInfo["device_uuid"]!,
// "os": Platform.isAndroid ? "Android" : "iOS",
// "os_version": deviceInfo["os_version"]!,
// "app_version": packageInfo.version,
// });
// print("bind device to session response $bindDeviceToSessionResponse");
// if (bindDeviceToSessionResponse?.statusCode == 200) {
// await _openWebView(prospectId);
// } else {
// debugPrint(
// 'Error setting up device session: $bindDeviceToSessionResponse');
// await _openWebView(prospectId);
// }
// } catch (e) {
// debugPrint('Error setting up device session: $e');
// rethrow;
// }
// }
Future<void> _openWebView1(BuildContext context, String prospectId) async {
final cookiesBefore = await cookieBridge.checkSession();
print('Cookies before WebView: $cookiesBefore');
final webView = await cookieBridge.getWebView(
url:
"https://uat2cbp.dcbbank.com/api/user/mock?prospect_id=6aa0a5c5-a813-4030-aa9e-fa9866cb826b&kid=PC7WzxKenHnnR58qkhGH4tt02WH1c1VI&redirect_url=https://spense.money&device_binded=true",
callback: (WebViewCallback action) {
switch (action.type) {
case WebViewCallbackType.redirect:
print(
"--------------- Redirect Redirected with status main: ${action.status}");
break;
case WebViewCallbackType.logout:
print("--------------- Redirect User logged out main");
break;
}
},
whitelistedUrlsAndroid: [
"https://uat2cbp.dcbbank.com",
"y",
"https://10.210.176.124",
"https://10.73.227.183"
"api.razorpay.com",
"https://sbmsmartbankinguat.sbm.bank.in",
"https://10.38.23.183"
],
whitelistedUrlsIos: [
"whitlelistedUrls",
"https://10.210.176.124",
"api.razorpay.com",
"https://sbmsmartbankinguat.sbm.bank.in",
"https://10.38.23.183"
],
hostName: "https://sbmsmartbankinguat.sbm.bank.in",
);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => webView,
));
}
// Future<void> _loginAndNavigate(String prospectId) async {
// String token = await createToken();
//
// open(context, "module", token,
// (WebViewCallback action) {
// switch (action.type) {
// case WebViewCallbackType.redirect:
// print("Redirected with status: ${action.status}");
// break;
// case WebViewCallbackType.logout:
// print("User logged out");
// break;
// }
// });
// _openWebView(prospectId);
// }