How to Scan Fingerprints with Async PHP and React Native — SitePoint

How to multi-factor authentication with Fingerprints scans, Async PHP and React Native

  • Our composer.json file could look something like:
    {
    “scripts”: {
    “dev”: “vendor/bin/aerys -d -c loader.php”,
    “prod”: “vendor/bin/aerys -c loader.php”
    },
    “require”: {
    “amphp/aerys”: “dev-amp_v2”,
    “pre/kitchen-sink”: “^0.1.0”
    },
    “autoload”: {
    “psr-4”: {
    “App\\”: “app”
    }
    },
    “config”: {
    “process-timeout”: 0
    },
    “minimum-stability”: “dev”,
    “prefer-stable”: true
    }

    This is from composer.json in the server project

    We can also set up a placeholder for requesting scans, along with an HTTP GET route to get to it:
    namespace App\Action;

    use Aerys\Request;
    use Aerys\Response;

    class ScanAction
    {
    public function __invoke(Request $request, Response $response)
    {
    $response-end(“requesting a scan…”);
    }
    }

    This is from app/Action/ScanAction.

  • pre in the server project

    use Aerys\Router;
    use App\Action\ScanAction;

    return (Router $router) = {
    $router-route(
    “GET”, “/scan”, new ScanAction
    );
    };

    This is from routes/web.

  • pre in the server project

    And we can start the server up with a server config file and pre-processor loader script:
    $port = 8080;

    $host = new $port);

    $host-use($router = Aerys\router());

    $web = process ‘http://127.0.0.1:{$port}’ | pbcopy”);

    This is from config.pre in the server project

    return Pre\processAndRequire(__DIR__ . “

  • Let’s add web sockets to our server:
    namespace App\Socket;

    use Aerys\Request;
    use Aerys\Response;
    use Aerys\Websocket;
    use Aerys\Websocket\Endpoint;
    use FingerprintSocket implements Websocket
    {
    private $endpoint;
    private $connections = [];

    public function onStart(Endpoint $endpoint)
    {
    $this-endpoint = $endpoint;
    }

    public function onHandshake(Request $request,
    Response $response)
    {
    // $origin = $request-getHeader(“origin”);
    //
    // if ($origin !

  • == “http://127.0.0.1:8080”) {
    // $response-setStatus(403);
    // $response-end(“origin not allowed”);
    // return null;
    // }

    $info = return $info[“client_addr”];
    }

    public function onOpen(int $clientId, $address)
    {
    $this-connections[$clientId] = $address;
    }

    public function onData(int $clientId, Message $message)
    {
    $body = yield $message;

    yield $this-endpoint-send(
    $payload, $clientId
    );
    }

    public function onClose(int $clientId,
    int $code, string $reason)
    {
    }

    public function onStop()
    {
    // nothing to see here…
    }
    }

    This is from in the server project

    use Aerys\Router;
    use App\Action\ScanAction;
    use (Router $router) = {
    $router-route(
    “GET”, “/scan”, new ScanAction
    );

    $router-route(
    “GET”, “/ws”, Aerys\websocket(new FingerprintSocket)
    );
    };

    This is from routes/web.

In this comprehensive and advanced tutorial, Chris shows us how to scan fingerprints with Async PHP and React Native. The future is here!

@MarcosBL: How to multi-factor authentication with Fingerprints scans, Async PHP and React Native

This article was peer reviewed by Adedayo Adeniyi. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

We live in interesting times. A short while ago, a company called OfferZen announced a new, programmable credit card. It’s been a long time since I was this excited to get my hands on a piece of tech. My mind has been brimming with ideas ever since.

So, I decided to write about one of them!

I’m going to describe the process of building custom multi-factor authentication for all transactions. I don’t want to do the usual (and boring on its own) SMS or push notification one-time-password stuff. I want to build a fingerprint scanner right into my phone.

In this tutorial, we’re going to look at how to set up a simple iOS app using React Native. We will also set up an asynchronous HTTP server, with a web socket connection to the app.

We will follow this up by adding fingerprint scanning capabilities to the app, and asking for these fingerprint scans from the HTTP server. Then we will build an endpoint through which GET requests can request a fingerprint scan and wait for one to occur.

There’s a lot to cover, so I’ve chosen to leave the programming of the credit card for another tutorial. This tutorial will be useful on its own, but even better alongside the next one!

What is React Native?

If you’ve been building websites for a while, then you’ve probably heard the name React. It’s an interface builder library (among other things). It introduces many new and interesting ideas to the world of front-end development. One of them is that interfaces are easier to build when you think of them one discrete component at a time. Kind of like how one “eats an elephant one bite at a time“.

React Native takes these ideas one step further, by providing a build chain to compile front-end technologies (like HTML, Javascript, and CSS) to native iOS and Android applications.

With React Native, it’s possible to write code very similar to what you’d find in a web project, and have it work flawlessly for most smartphone users. So why are we talking about it in the PHP channel? As you’ll see, this platform is so accommodating that a modest amount of Javascript knowledge is enough to build something useful. We don’t need to know Java or Objective-C or Swift!

command-line tool.

The docs include steps to create a new project and run it in the simulator. There’s no point continuing beyond this point if you can’t get the new application to run. If that’s the case, talk to me on Twitter or in the comments.

It’s tempting to think that React Native only installs a generalized Javascript API to use, but that’s not the case. One of its best features (in my opinion) is the powerful native module support.

In the case of fingerprint scanning, there is no native Javascript API. But there are a plethora of native modules which provide one. I googled “react native ios fingerprint” and the first match appears to work wonderfully:

file is a bit messy, but it is mostly sufficient to try TouchID. After a bit of tidying up, it should look similar to this:

If you’re unsure about the general structure of this, it’s probably a good time to brush up on React development. There are plenty of great courses on the subject, ours included.

By default, this will automatically fail. The simulator is set to not have enrolled fingerprints by default. When you open the app with this new code, you should see the failure message.

To change this, go to “Hardware” menu and select “Touch ID” → “Toggle Enrolled State”. Once you refresh (which you can do with ⌘ + R), you should see the prompt to scan your fingerprint. Since the simulator doesn’t have a way to physically do this, head back to the same “Touch ID” menu, and select “Matching Touch”. You should then see the success message.

On it’s own, this isn’t yet useful. We can simulate a fingerprint scan, but it’s happening automatically and not when needed. We should create a server, so that fingerprints can be requested.

My favorite kind of PHP server is an async PHP server. I’ve written about this many times before, so feel free to check out more detailed explanations on the topic: Game Development with ReactJS and PHP and Procedurally Generated Game Terrain with ReactJS, PHP, and Websockets.

I’ll not go too deeply into what things are doing, but feel free to dive into the code for this tutorial to learn about things I don’t mention here.

file could look something like:

We can also set up a placeholder for requesting scans, along with an HTTP GET route to get to it:

And we can start the server up with a server config file and pre-processor loader script:

creates a new async Aerys server, and loads the routes file. The routes file registers a GET route to the ScanAction class.

, we should see the message “requesting a scan…”. This is good. Let’s add web sockets to our server:

endpoint, we can test this out:

method:

To see these console messages, you’ll need to enable remote debugging.

and select “Debug Remote JS”. This will open a new Chrome tab. Open the developer tools pane of this new tab, then refresh the app. This should lead to seeing “hi” in the console, as it is echoed back from the server.

Let’s customize the React Native code to listen for requests to scan fingerprints:

, we request a fingerprint scan. Whether the fingerprint scan completes successfully or not, we send a serialized JSON object with details about the event.

We also need to adjust the server to deal with this new kind of message:

We provide a reference to the socket class to the action class. This means we can call methods on the socket class in response to HTTP requests:

route is called, we request a new fingerprint scan from the socket class. This is a delayed action (because the app must prompt and wait for the scan), so we can expect to use promises:

methods). We store a reference to the deferred object, and broadcast its identity (and a request to scan) to all connected web socket clients.

messages from the app. We find the related deferred object, and resolve or fail it appropriately.

At that point, the action’s yield statement resolves and we can respond, either successfully or not. Here’s what it looks like, all put together:

Given how little JavaScript we needed to write, and how cool the interactivity between iOS and the async PHP server is, I think this has been a huge success. We’ve created a way to request fingerprint scans via a simple HTTP GET request. That’s huge on its own, but now think about how we could integrate this during a credit card authorization step!

More on this in a follow-up – until then, please let us know what you think in the comments section below!

How to Scan Fingerprints with Async PHP and React Native — SitePoint