Flutter: Create a Password Strength Checker from Scratch

Updated: September 15, 2023 By: A Goodman Post a comment

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).

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:

You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Related Articles