Hello folks. Today, we will create a password strength checker in Flutter from scratch without using any third-party plugins. Without any further ado, let’s get started (this article was published a very long time ago but I’ve recently updated it with Material 3).
Table of Contents
Overview
Each application will have a different way of assessing password strength. In the example below, we will measure a password based on the following criteria:
- Less than 6 characters in length: Weak
- Length from 6 to less than 8 characters: Medium (acceptable but not robust)
- 8 characters or more: Strong (but not the best)
- 8 characters or more and contains both digits and letters: Great
To check if a password contains both digits and letters, we will use regular expressions like this:
RegExp numReg = RegExp(r".*[0-9].*");
RegExp letterReg = RegExp(r".*[A-Za-z].*");
if (!letterReg.hasMatch(_password) || !numReg.hasMatch(_password)) {
// Password doesn't contain both letter and digit characters
} else {
// Password contains both letter and digit characters
}
You can see the detailed guide about Dart’s regular expressions in this article.
The Example
App Preview
In this example, the password strength will be indicated with a LinearProgressIndicator
. In addition, if the password is below medium, the Continue button will be disabled.
A short video is worth more than thousands of words:
The Complete Code
The full source code with explanations in main.dart
(with explanations):
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'KindaCode.com',
theme: ThemeData(
// enable Material 3
useMaterial3: true,
primarySwatch: Colors.indigo,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late String _password;
double _strength = 0;
// 0: No password
// 1/4: Weak
// 2/4: Medium
// 3/4: Strong
// 1: Great
RegExp numReg = RegExp(r".*[0-9].*");
RegExp letterReg = RegExp(r".*[A-Za-z].*");
String _displayText = 'Please enter a password';
void _checkPassword(String value) {
_password = value.trim();
if (_password.isEmpty) {
setState(() {
_strength = 0;
_displayText = 'Please enter you password';
});
} else if (_password.length < 6) {
setState(() {
_strength = 1 / 4;
_displayText = 'Your password is too short';
});
} else if (_password.length < 8) {
setState(() {
_strength = 2 / 4;
_displayText = 'Your password is acceptable but not strong';
});
} else {
if (!letterReg.hasMatch(_password) || !numReg.hasMatch(_password)) {
setState(() {
// Password length >= 8
// But doesn't contain both letter and digit characters
_strength = 3 / 4;
_displayText = 'Your password is strong';
});
} else {
// Password length >= 8
// Password contains both letter and digit characters
setState(() {
_strength = 1;
_displayText = 'Your password is great';
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('KindaCode.com'),
),
body: Padding(
padding: const EdgeInsets.all(30),
child: Column(
children: [
TextField(
onChanged: (value) => _checkPassword(value),
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: 'Password'),
),
const SizedBox(
height: 30,
),
// The strength indicator bar
LinearProgressIndicator(
value: _strength,
backgroundColor: Colors.grey[300],
color: _strength <= 1 / 4
? Colors.red
: _strength == 2 / 4
? Colors.yellow
: _strength == 3 / 4
? Colors.blue
: Colors.green,
minHeight: 15,
),
const SizedBox(
height: 20,
),
// The message about the strength of the entered password
Text(
_displayText,
style: const TextStyle(fontSize: 18),
),
const SizedBox(
height: 50,
),
// This button will be enabled if the password strength is medium or beyond
ElevatedButton(
onPressed: _strength < 1 / 2 ? null : () {},
child: const Text('Continue'))
],
),
));
}
}
Conclusion
We’ve built a password strength gauge in Flutter without using any third-party packages. From this point, you can improve it and add your own logic and measuring metrics. If you’d like to explore more new and exciting stuff about Flutter and Dart then have a look at the following articles:
- Flutter: How to Draw a Heart with CustomPaint
- Implementing Tooltips in Flutter
- Flutter: Stream.periodic example
- Flutter: FilteringTextInputFormatter Examples
- 2 Ways to Create Flipping Card Animation in Flutter
- Flutter & SQLite: CRUD Example
You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.