In today’s mobile app world, user authentication plays a crucial role in ensuring both security and user experience. While FlutterFlow offers a robust framework for building applications, it currently lacks built-in support for biometric authentication. In this article, I’ll walk you through how I managed to let users log in with their fingerprint or face recognition by using Flutter Secure Storage. Plus, I’ll share how I tackled the security concerns that come with storing sensitive information like emails and passwords.
Biometric Verification
One of the utility actions that FlutterFlow offers is Biometric Verification, which acts as a security perimeter by asking the user for their phone’s biometric information before executing other actions. However, during my initial research I was looking for ways to have biometric authentication. The closest thing I found was advice on a forum, suggesting to build the logic using the Biometric Verification action and then storing the user’s email and password in the App State. Since we wouldn't store that kind of information in our database, I thought it sounded too risky… and I was right.
The problem with using App State
When using App State you can choose to secure persisted fields in order to securely store sensitive information on the device with data encryption, making use of Keychain for iOS and KeyStore for Android. So far everything sounds great, until you realize… on app initialization, all values are decrypted and left unprotected for as long as the app runs. And let’s be honest, users usually leave apps running in the background instead of closing them.
On the file main.dart, you can find the next couple lines of code:
So, if you were to store the user’s email and password in the App State, this what the generated code executed on app initialization would look like:
Solution
In order to ensure that the email and password were not stored unencrypted throughout the app’s lifecycle, I decided to create a set of custom actions using the same package, Flutter Secure Storage, decrypt the values only when needed and then discard them immediately after use. We can still use App State for less sensitive information, so I created a boolean variable to verify when the user has enabled this option for authentication.
Custom Action: Set Login Credentials
Custom Action: Get Login Credentials
Custom Action: Delete Login Credentials
Bringing It All Together
Make sure to include in your signup and sign in flows a modal to offer the user to enable Biometric Authentication for their next login. If the user agrees to it, your action flow should look something like this:
Next, validate that the option to Sign In with Biometrics in your page has conditional visibility dependent on our App State variable:
For the login when the user selects this option, use this action flow:
Make sure to use the values of your custom action directly in the Log In action and don’t store them anywhere. And that’s it! We have enabled secure biometric authentication for our app. For a complete process, don’t forget to add an option in the settings for the user to disable this at any time. For doing so, simply use this couple of actions:
Finally, make sure to use snack bars or other ways of user feedback throughout the entire process so the user can know the results of every step.
Conclusion
By implementing this solution, you can provide your users with a secure and convenient way to log in using biometric authentication. This method not only enhances the user experience but also prioritizes security by ensuring sensitive information is stored only temporarily and securely.
As FlutterFlow continues to evolve, I look forward to seeing native support for biometric authentication in future releases. In the meantime, I hope you found this custom solution helpful if you’re running into similar challenges!
Interested in a free app review?
Schedule a call