Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Local Authentication in Flutter — Passcode

Hello and welcome to my new blog on Passcode authentication. In this blog, we shall learn and explore how we can implement a simple local authentication using a passcode. This type of authentication is much secure and private also it is extremely fast. Another user how doesn’t know your passcode can’t access your app content directly. This type of authentication removes the server-side errors and provides clean checkout to access the app.

Please give it a try by yourself and try to find out how we can implement this type of functionality with ease. Hopefully, we will require some pub packages as well so please try to find out by yourself which package might help to implement this functionality.

Demo Module:

So what your thought on this? please share your approach on this functionality. Now here is mine, so let’s go……


The packages that we are going to use are:

get_it | Dart Package
This is a simple Service Locator for Dart and Flutter projects with some additional goodies highly inspired by Splat…pub.dev

provider | Flutter Package
English | Português | 简体中文 A wrapper around InheritedWidget to make them easier to use and more reusable. By using…pub.dev

shared_preferences | Flutter Package
Wraps platform-specific persistent storage for simple data (NSUserDefaults on iOS and macOS, SharedPreferences on…pub.dev

  • We will use the provider package for state management.
  • shared_preferences package us various methods to store our data inside our app locally and safely.
  • get_it help us to register our services in a very simple and easy way.

State management technique used in this module

Before getting into the functionality part let’s first learn the state management structure of the app.

  • We have created a file baseModel.dart that contains a BaseModel class that extends ChangeNotifier . In this file, we will write all the common methods that we will use throughout our app such as implementing circular progress indicator when and method is awaited.
  • For each screen, we will create a separate file that will contain all the code that will handle all the methods that will provide the data for that particular screen from the internet server or local server. Each file will extends BaseModel in general ChangeNotifier.
  • We will create a separate widget that we will use to access the provider methods or class.BaseView can only be used for the model class that extends BaseModel .
  • Please go through the bellow blogs for a better understanding of this state management technique.

Flutter and Provider Architecture using Stacked
In this series, we will be taking an extensive look at how I will architect the applications for my clients moving…www.filledstacks.com

Let’s start our code:

  • Create a baseModel.dart file that extends ChangeNotifier.
import 'package:flutter/material.dart';

class BaseModel extends ChangeNotifier {}
  • Create a sharedPrefs.dart file that will contain the passCode uploading and fetching code from the local store and this model will be used for the passcode check out screen.

Uploading the passCode value:

setPassCode(int passCodeValue) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setInt('passCode', passCodeValue);
}

sharedPreferences is an object of SharedPreferences that will provide us access to all the methods. This method takes a passCodeValue int that will be stored under the ‘passCode' key.

sharedPreferences.setInt('passCode', passCodeValue);

setInt method creates a passCode key in the app local storage and store the passCodeValue in it.

Fetching the passCode value:

First, create a variable that will store the fetched value of the passCode from the local server.

int _passCode;

int get passCode => _passCode;

passCode is a getter of _passCode that get and store the value of _passCode whenever it is changed.

getPassCode method is used to fetch the value of passCode . To get the value of the passCode key SharedPreferences provides us getInt method.

getPassCode() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
int code = sharedPreferences.getInt('passCode');
print("**************" + code.toString());
_passCode = code;
notifyListeners();
}

Full File:

import 'package:local_passcode_auth/baseModel.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefs extends BaseModel {
int _passCode;

int get passCode => _passCode;

setPassCode(int passCodeValue) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setInt('passCode', passCodeValue);
//upload the passCodeValue
  }

getPassCode() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
int code = sharedPreferences.getInt('passCode');
//fetch the passCode value
print("**************" + code.toString());
_passCode = code;
notifyListeners();
//informs the passCode getter that the value has been changed and it will update the ui wherever it is used.
}
}
  • Regester all the models using the get_it

locator.dart file:

import 'package:get_it/get_it.dart';
import 'package:local_passcode_auth/sharedPrefs.dart';

import 'baseModel.dart';

final locator = GetIt.instance;

void setupLocator() {
locator.registerLazySingleton(() => BaseModel());
locator.registerLazySingleton(() => SharedPrefs());
}
  • initialize the setupLocator() method inside the main method
void main() {
setupLocator();
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.dark(),
darkTheme: ThemeData(),
home: MyApp(),
),
);
}

baseView.dart file:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'baseModel.dart';
import 'locator.dart';

class BaseView<T extends BaseModel> extends StatefulWidget {
final Widget Function(BuildContext context, T model, Widget child) builder;
final Function(T) onModelReady;

BaseView({@required this.builder, this.onModelReady});

@override
_BaseViewState<T> createState() => _BaseViewState<T>();
}

class _BaseViewState<T extends BaseModel> extends State<BaseView<T>> {
T model = locator<T>();

@override
void initState() {
if (widget.onModelReady != null) {
widget.onModelReady(model);
}
super.initState();
}

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>.value(
//builder: (context) => model,
child: Consumer<T>(builder: widget.builder),
//notifier: model,
value: model,
);
}
}

checkoutPage.dart file:

This page is our main page that will contain a simple TextField that will take the passCode from the user and verify it with the fetched Passcode, if both the values are the same then we will navigate it to the HomePage .

Here we will require the sharedPrefs fetch and upload methods that we have created in sharedPrefs.dart file.

To use SharedPrefs class we need to use the BaseView class. BaseView class provides us builder, onModelReady property to build the builder of the Consumer and onModelReady will be used to initialize the methods or values inside the initStatemethod.

Data Flow of this file:

  • When this Widget is called inside the init state model.setPassCode(1234), model.getPassCode() will be called so that the passCode getter in the sharedPrefs.dart can get the value of the passcode. BaseView provides us onModelReady method to initialize the methods inside the initState() method.
  • Now we can use use the value of the passCode getter inside our builder.
  • We have created a TextField that will take the value of passCode form the user and when the user will click on the right arrow button then the onPressed property of icon will check the condition if it is true then the user will be navigated to the HomePage.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:local_passcode_auth/baseView.dart';
import 'sharedPrefs.dart';
import 'homePage.dart';

// ignore: must_be_immutable
class CheckoutPage extends StatelessWidget {
TextEditingController textEditingController = TextEditingController();

@override
Widget build(BuildContext context) {
return BaseView<SharedPrefs>(
onModelReady: (model) {
model.setPassCode(1234);
model.getPassCode();
},
builder: (context, model, child) => Scaffold(
backgroundColor: Colors.black,
body: Padding(
padding: const EdgeInsets.all(10),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: TextField(
controller: textEditingController,
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: () {
if (model.passCode.toString() ==
textEditingController.text) {
Navigator.pop(context);
Navigator.of(context).push(PageRouteBuilder(
pageBuilder:
(context, animation, anotherAnimation) {
return HomePage();
},
transitionDuration: Duration(milliseconds: 600),
transitionsBuilder: (context, animation,
anotherAnimation, child) {
animation = CurvedAnimation(
curve: Curves.easeIn, parent: animation);
return SlideTransition(
position: Tween(
begin: Offset(-1.0, 0.0),
end: Offset(0.0, 0.0))
.animate(animation),
child: ScaleTransition(
scale: animation,
child: child,
),
);
}));
} else
print("failed");

print("************+++" + model.passCode.toString());
},
icon: Icon(Icons.forward),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
),
labelText: "Enter PIN",
),
obscureText: true,
autofocus: true,
cursorColor: Colors.grey,
keyboardAppearance: Brightness.dark,
keyboardType: TextInputType.number,
),
)
],
),
),
),
),
);
}
}

GitHub File:

flutter-devs/local_passcode_auth
A new Flutter application. This project is a starting point for a Flutter application. A few resources to get you…github.com


Thanks for reading this article ❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

If we got something wrong? Let me know in the comments. we would love to improve.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.

Leave comment

Your email address will not be published. Required fields are marked with *.