Type Here to Get Search Results !

Building a React App with Biometric Authentication

Building a React App with Biometric Authentication

In today’s digital age, ensuring robust security for applications is paramount. One effective method is implementing fingerprint security…

ReactJS Biometric Authentication

Building a React App with Biometric Authentication

In today’s digital age, ensuring robust security for applications is paramount. One effective method is implementing fingerprint security using WebAuthn. This blog will walk you through adding fingerprint authentication in a Node.js application using the SimpleWebAuthn library with a React.js frontend. We will cover both frontend and backend code to give you a complete understanding of the implementation.

Prerequisites

  • Basic understanding of Node.js, Express.js, and React.js.
  • Familiarity with handling AJAX requests.
  • A working Node.js environment.

Frontend Implementation

Let’s start by setting up the frontend. We’ll use React.js to handle the user interface for registering and authenticating fingerprints.

Setting Up React Project

First, create a new React project using Create React App:

npx create-react-app fingerprint-auth
cd fingerprint-auth
npm install @simplewebauthn/browser axios

Registering a Fingerprint

Create a component for registering a fingerprint:

// src/RegisterFingerprint.js
import React from 'react';
import axios from 'axios';
import { startRegistration } from '@simplewebauthn/browser';

const RegisterFingerprint = () => {
const registerPasskey = async () => {
try {
const res = await axios.post('/api/auth/register-challenge');
if (res.data.code === 200) {
const authResult = await startRegistration(res.data.data);
if (authResult) {
await axios.post('/api/auth/verify-challenge', {
challenge: res.data.data.challenge,
credential: authResult,
});
alert('Fingerprint registered successfully');
}
} else {
alert(res.data.message);
}
} catch (err) {
console.error(err);
}
};

return (
<div>
<button onClick={registerPasskey}>Register Fingerprint</button>
</div>

);
};

export default RegisterFingerprint;

Logging in with Fingerprint

Create a component for logging in using a fingerprint:

// src/LoginFingerprint.js
import React from 'react';
import axios from 'axios';
import { startAuthentication } from '@simplewebauthn/browser';

const LoginFingerprint = () => {
const biometricLogin = async () => {
try {
const res = await axios.post('/api/auth/login-challenge');
if (res.data.checkFingerPrint === 'false') {
alert('Please register biometric first');
return;
}
if (res.data.code === 200) {
const authResult = await startAuthentication(res.data.data);
const verifyRes = await axios.post('/api/auth/verify-login-challenge', {
challenge: res.data.challenge,
credential: authResult,
});
if (verifyRes.data.code === 200) {
window.location.href = '/dashboard';
} else {
alert(verifyRes.data.message);
}
} else {
alert(res.data.message);
}
} catch (err) {
console.error(err);
}
};

return (
<div>
<button onClick={biometricLogin}>Login with Fingerprint</button>
</div>

);
};

export default LoginFingerprint;

Backend Implementation

Now, let’s move on to setting up the backend. We will use the SimpleWebAuthn library to handle the WebAuthn protocol.

Dependencies

First, install the required dependencies:

npm install @simplewebauthn/server express body-parser

Setting Up Routes

Below are the backend routes for registering and verifying fingerprints.

Register Challenge Route

// routes/auth.js
const { generateRegistrationOptions, verifyRegistrationResponse } = require('@simplewebauthn/server');
const express = require('express');
const router = express.Router();

router.post('/register-challenge', async (req, res) => {
try {
const challengePayload = await generateRegistrationOptions({
rpID: 'localhost',
rpName: 'My Application',
userName: req.user.id,
});

if (challengePayload) {
res.json({ code: 200, data: challengePayload, status: 'success' });
} else {
res.json({ code: 500, message: 'Something went wrong. Please contact your administrator.', status: 'error' });
}
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Internal Server Error' });
}
});

module.exports = router;

Verify Challenge Route

// routes/auth.js
router.post('/verify-challenge', async (req, res) => {
try {
const verificationResult = await verifyRegistrationResponse({
expectedChallenge: req.body.challenge,
expectedOrigin: 'https://myapp.example.com',
expectedRPID: 'myapp.example.com',
response: req.body.credential,
});

if (verificationResult.verified) {
// Save the fingerprint information to the database
await saveFingerprint(req.user.id, verificationResult.registrationInfo);
res.json({ code: 200, status: 'success', message: 'Biometric Registration Successful!' });
} else {
res.json({ code: 500, message: 'Invalid user!', status: 'error' });
}
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Internal Server Error' });
}
});

Login Challenge Route

// routes/auth.js
const { generateAuthenticationOptions, verifyAuthenticationResponse } = require('@simplewebauthn/server');

router.post('/login-challenge', async (req, res) => {
try {
const user = await getUser(req.user.id); // Fetch the user from the database
if (!user || !user.fingerprint) {
return res.json({ code: 500, message: 'Please register biometric first', status: 'error', checkFingerPrint: 'false' });
}

const options = await generateAuthenticationOptions({
rpID: 'myapp.example.com',
userVerification: 'preferred',
});

res.json({ code: 200, data: options, challenge: options.challenge, status: 'success', checkFingerPrint: 'true' });
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Internal Server Error' });
}
});

Verify Login Challenge Route

// routes/auth.js
router.post('/verify-login-challenge', async (req, res) => {
try {
const user = await getUser(req.user.id); // Fetch the user from the database

if (!user || !user.fingerprint) {
return res.json({ code: 500, message: 'Fingerprint not found', status: 'error' });
}

const result = await verifyAuthenticationResponse({
expectedChallenge: req.body.challenge,
expectedOrigin: 'https://myapp.example.com',
expectedRPID: 'myapp.example.com',
response: req.body.credential,
authenticator: JSON.parse(user.fingerprint),
});

if (result.verified) {
res.json({ code: 200, status: 'success', message: 'Login Successful!' });
} else {
res.json({ code: 500, message: 'Invalid user!', status: 'error' });
}
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Internal Server Error' });
}
});

Conclusion

Implementing fingerprint security in your Node.js application using WebAuthn is a robust way to enhance security. By following the steps outlined in this guide, you can add fingerprint authentication to your application, providing users with a secure and convenient login method.

Make sure to customize the dummy data, URLs, and database interactions to fit your application’s specific needs. Happy coding!

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.

Top Post Ad

Below Post Ad