Authentication is hard. Let FACEIO handle it for you
Tags: react, auth, javascript, beginners
Published: 2022-12-04 07:01:11

There are very few companies which implement their own authentication system. This is because even big and advanced companies can fall prey to security attacks. This leads to awkward lawsuits and in some cases company's downfall. 

Authentication systems are developed as components in a complex application or as a service. If the company is developing the authentication system for providing identity as a service then it makes sense to spend time and resources. But if it is being used as one of the components in a complex application then even the big and advanced companies try to use what is already tried and tested. This approach not only saves time and money but it will provide much-needed security for such an important component.

Developers have been developing and optimising the authentication system for a long time now. It is still a complex feature which needs dedicated time and resources. Handling user data is probably one of the most complex parts to get right in any application (web or not). There are just so many places for something to go wrong. It becomes really hard to ensure that your app is really secure.

It’s not just login form -> check username/password -> set the cookie. It has a lot of other things to think about:

Cookie security, Password requirements, Storing passwords in the database, Email vs username, Rate-limiting authentication attempts, Captcha, Password reset, 2FA, Force 2FA by admin configuration and whatnot.

This is why it is essential that you follow the latest best practices when designing an authentication system for your web application. Better yet, you could get someone more experienced to do it for you while you focus on the core features of your app.

This is where [FACEIO](https://faceio.net/) comes in handy. In this case FACEIO “someone more experienced” will take care of authentication for us.

With [FACEIO](https://faceio.net/), you can leverage the experience of some of the smartest minds in software development to build an authentication system that has been battle tested for years and vetted by the pros in the industry.

FACEIO is a facial authentication framework that is to be implemented on websites or web applications via a simple JavaScript snippet. It authenticates users using face recognition instead of the traditional login/password pair or OTP code. It is a cross-browser, Cloud  & On-Premise deployable.

In my opinion, it is the easiest way to add passwordless authentication to websites or web applications. Simply [implement](https://faceio.net/integration-guide) `fio.js` on your website, and you will be able to **instantly authenticate your existing users, and enroll new ones via Face Recognition** using their computer Webcam or smartphone frontal camera on their favourite browser.

Enough of theory, let me show you a working demo on how to integrate and use FACEIO facial authentication in a reactJS application.

![folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwks09v0uxlsopsjtkll.png)
This is the folder structure of my ReactJS application which I am going to use for FACEIO demo.

The first step in integration after setting up a ReactJS project is to integrate fio.js cdn within the public/index.html file as shown in the following section
```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>

  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <script src="https://cdn.faceio.net/fio.js"></script>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
```
As you can see I have added facio cdn link - `https://cdn.faceio.net/fio.js` within the `<script></script>` tag in `index.html` file like this

```html
<script src="https://cdn.faceio.net/fio.js"></script>
```
The second part is easier than the first one. You just have to invoke either enroll() function to sign up new users for your application or invoke authenticate()  function to sign in already authenticated users.

I have done this in my App.js file. But you are free to do it in any file. Let add the code snippet for you for better understanding.
src/App.js

```js
import React, { useState, useEffect } from "react";
import "./styles.css";
import { handleError } from "./errorHandler";
let faceio;
export default function App() {
  const [faceid, setFaceId] = useState(null);
  const [accountExistString, setAccountExistString] = useState("");
  useEffect(() => {
    faceio = new faceIO("<application-id>");
  }, []);
  useEffect(() => {
    setAccountExistString("");
  }, [faceid]);
  const handleNewUser = async () => {
    try {
      let response = await faceio.enroll({
        locale: "auto"
      });
      setFaceId(response.facialId);
    } catch (error) {
      console.log("error", error);
      handleError(error);
      if (error === 20) {
        setAccountExistString("Your account exists, Please Sign In");
      }
      if (error === 9 || error === 6) {
        setAccountExistString("Something went wrong! Please try again!");
      }
      if (error === 13) {
        window.location.reload();
      }
    }
    console.log("This is done");
  };

  const handleAuthentication = async () => {
    try {
      let response = await faceio.authenticate({
        locale: "auto"
      });
      setFaceId(response.facialId);
    } catch (error) {
      if (error === 20) {
        window.location.reload();
      }
    }
  };

  const handleLogout = async () => {
    window.location.reload();
  };

  return (
    <div className="App">
      {faceid && (
        <>
          <div>
            <img src="./padlock.svg" alt="faceid" height="300" width="200" />
          </div>
          <h1>Face Identity Verified</h1>
          <button className={"mybutton"} onClick={handleLogout}>
            Logout
          </button>
        </>
      )}
      {!faceid && (
        <>
          <h1> Verify Face Identity</h1>
          <img src="./faceid.svg" alt="faceid" height="300" width="200" />
          <button className={"mybutton"} onClick={handleAuthentication}>
            Sign In
          </button>
          <button className={"mybutton"} onClick={handleNewUser}>
            Sign Up
          </button>
          {accountExistString && <h3>{accountExistString}</h3>}
        </>
      )}
    </div>
  );
}
```
There are three important things happening here 

1. Initialise your faceio application using `<application-id>`. Application id you get by signing up [FACEIO](https://console.faceio.net/) .
2. Onclick event handling for Sign In and Sign Up buttons. On Sign Up, I am invoking the following enroll() function of fio.js . And on Sign In, I am invoking authenticate() function to sign in enrolled users. I would suggest you go through the [integration](https://faceio.net/integration-guide) documentation to better understand the use of fio.js. 
3. Handling errors from fio.js. I am handling all type errors from fio.js. You can find the error codes and their description in the following fio.js documentation. [fio.js error codes](https://faceio.net/integration-guide#error-codes).

For the full code, you can clone my `faceiodemo` GitHub repo using https://github.com/sonu0702/faceiodemo.git

Here is the preview of my demo app which I have deployed on [vercel](https://vercel.com/).

https://csb-kwbgjs-nq8tfdpqc-sonu0702.vercel.app/

[FACEIO](https://faceio.net/) takes care of that too. If you tried my demo application you would know that once the face recognition is done you will require to input a PIN. This pin combined with facial recognition will be used to authenticate you.

As a developer, I can say that overall FACEIO gives a hassle-free frontend development experience. Frontend developers do not have to worry about creating a form, handling form errors and all other things which we have been dealing with for so long. For backend developers, [FACEIO](https://faceio.net/) gives webhook events on creating new users. These events can be listened to and stored to authenticate other API flows of the application.