auth flow flutter

Simple authentication flow in flutter using shared preferences

Overview

Starting a project without proper planning can quickly become overwhelming. To that end, developing a good authentication flow is equally important. In this guide, we’ll create a user authentication flow in flutter application with the help of a shared preferences library.

Although there are many guides available and explains the same topic, my intention is to simplify the authentication pattern without using complex libraries and architecture. We’ll create a simple folder structure to deal with the navigation based on the user login status.

To follow along this tutorial, make sure you have installed the following library in your project.

Shared preferences a library used to store data as a key value pair. If you are coming from a web development background it’s similar to local storage. Install here.

Project setup

We’ll now create a new flutter project using the command given below. For the sake of this guide, I’m naming the app as “auth_flow” but you can name it as whatever you want.

$ flutter create auth_flow

Once the project get created open the project in your favourite editor. As I use visual studio code I can open the project using,

$ cd auth_flow && code .

We’ll have the following screens in our application.

  • Entry screen
  • Login screen
  • Home screen

Refer the following picture to understand the user flow of the application.

authentication flow flutter app
Authentication flow in flutter

Once you opened the project in the editor create the following files. In the lib folder create a folder names as “UI” and create the entry.dart, login.dart and home.dart files. If you are building a large project, make sure you separate these files to their own modules. Like auth module, home module etc.

authentication flow flutter
Folder structure

As of now, we have created the required project structure and we can start working on the authentication flow in flutter. Open up your main.dart file and add the following content to it.

import 'package:auth_flow/ui/entry.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: EntryApp(),
    );
  }
}

Here, we have created a class named as MyApp and returning the EntryApp class to deal with authentication flow in the flutter app. Open the entry.dart file and add the following codes to it.

import 'package:auth_flow/ui/home.dart';
import 'package:auth_flow/ui/login.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

//Entry point of the app
class EntryApp extends StatefulWidget {
  @override
  _EntryAppState createState() => _EntryAppState();
}

class _EntryAppState extends State<EntryApp> {
  bool isUserSignedIn = false;

  @override
  void initState() {
    _checkLoginStatus();
    super.initState();
  }

  //check user login status
  Future<String> _checkLoginStatus() async {
    SharedPreferences shared = await SharedPreferences.getInstance();

    //Run the code after 200 milliseconds
    return Future.delayed(Duration(milliseconds: 200), () {
      String userToken = shared.getString('userToken') ?? "";
      if (userToken.length != 0) {
        if (this.mounted) {
          setState(() {
            isUserSignedIn = true;
          });
        }
      }
      return userToken;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _checkLoginStatus(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.data.length != 0) {
            return LoginPage();
          } else {
            return HomePage();
          }
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    );
  }
}

As you can see I have used a future builder to check the user token which is stored inside the shared preferences. Once the app loads to the entry page, it’ll run the _checkLoginStatus function in the future builder and redirect the user to the specific page based on the user token. I’ve also added a Future.delayed method to make the UI a little intuitive by adding 200ms of delay which shows a nice progress indication when the app starts.

When the app redirects you to the Login page you can setup the user Token to the shared preferences. An example will be like,

login.dart

//Store the user token
_addTokenToStorage() {
   SharedPreferences shared = await SharedPreferences.getInstance();
   shared.setString('userToken', "Q2df7YhKl");
 }

Conclusion

And there we have it, we have successfully created a very simple authentication flow in flutter application. To extend the functionalities you can sign in the user using firebase or any other backend service and store the token inside the shared preferences. This helps us to redirect the user to the home page without showing the login page all the time. This implementation can be further extended to use an architectural pattern like BloC. I hope you enjoyed the post. Thank you!

Leave a Comment

Your email address will not be published.