The world of web security is constantly evolving, and staying ahead of emerging threats requires constant vigilance. One of the most significant developments in recent years is WebAuthn, a new and powerful way to authenticate users. In this blog post, we’ll dive deep into what WebAuthn is, why it’s important, how to set it up in a simple Node.js + React codebase, and the advantages it brings to the table.
What is WebAuthn
WebAuthn, short for Web Authentication, is a web standard developed by the World Wide Web Consortium (W3C) and the FIDO Alliance. This standard enables passwordless, secure, and easy-to-use authentication methods for web applications. WebAuthn relies on public key cryptography, allowing users to authenticate using a variety of “authenticators” such as biometric devices, mobile phones, or FIDO2 security keys.
Why WebAuthn is Important
WebAuthn addresses some of the most pressing issues in web security, including:
- Password Problems: Passwords have been the Achilles’ heel of online security for years. They are often weak, reused across multiple sites, and susceptible to various attacks such as phishing or brute force. WebAuthn eliminates the need for passwords, significantly reducing these risks.
- Phishing Prevention: With WebAuthn, user credentials are never sent to the server. Instead, the authenticator creates a unique, encrypted signature for each website. This makes phishing attacks much more difficult to execute.
- Enhanced User Experience: Users no longer need to remember complex passwords or face account lockouts due to forgotten credentials. WebAuthn allows for a smooth and secure login experience using biometrics or security keys.
Setting Up WebAuthn in a Simple Node.js + React Codebase
To implement WebAuthn, follow these steps:
Step 1: Install Dependencies
In your Node.js project, install the necessary dependencies:
npm install --save fastify fastify-plugin webauthn fastify-cors
Step 2: Set Up the Server
Create a new file called webauthn.js
and add the following code to set up your Fastify server and WebAuthn routes:
const fastify = require('fastify')({ logger: true })
const webAuthn = require('webauthn')
const fastifyCors = require('fastify-cors')
fastify.register(fastifyCors, {
origin: '*', // Adjust this value to the correct origin for your client app
methods: ['POST']
})
fastify.post('/register', async (request, reply) => {
const options = webAuthn.generateRegistrationOptions()
reply.send(options)
})
fastify.post('/register/complete', async (request, reply) => {
const result = webAuthn.verifyRegistration(request.body)
if (result.verified) {
// Save the user's public key and other relevant data in your database
reply.send({ status: 'OK' })
} else {
reply.code(400).send({ status: 'Failed', message: 'Registration failed' })
}
})
fastify.post('/login', async (request, reply) => {
const options = webAuthn.generateAuthenticationOptions()
reply.send(options)
})
fastify.post('/login/complete', async (request, reply) => {
const result = webAuthn.verifyAuthentication(request.body)
if (result.verified) {
// Log in the user and set up a session
reply.send({ status: 'OK' })
} else {
reply.code(400).send({ status: 'Failed', message: 'Authentication failed' })
}
})
fastify.listen(3001, err => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
Step 3: Set Up the Client
In your React project, create a new file called WebAuthn.js
and add the following code:
import React from 'react'
import { create, get, supported } from '@github/webauthn-json'
class WebAuthn extends React.Component {
async handleRegister() {
if (!supported()) {
alert('WebAuthn not supported in your browser')
return
}
const response = await fetch('/register', { method: 'POST' })
const options = await response.json()
const credentials = await create(options)
const res = await fetch('/register/complete', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
const result = await res.json()
if (result.status === 'OK') {
alert('Registration successful')
} else {
alert('Registration failed: ' + result.message)
}
}
async handleLogin() {
if (!supported()) {
alert('WebAuthn not supported in your browser')
return
}
const response = await fetch('/login', { method: 'POST' })
const options = await response.json()
const assertion = await get(options)
const res = await fetch('/login/complete', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(assertion)
})
const result = await res.json()
if (result.status === 'OK') {
alert('Login successful')
} else {
alert('Login failed: ' + result.message)
}
}
render() {
return (
<div>
<button onClick={() => this.handleRegister()}>Register</button>
<button onClick={() => this.handleLogin()}>Login</button>
</div>
)
}
}
export default WebAuthn
WebAuthn is a game-changing technology that promises to revolutionize the way we handle authentication on the web. By implementing WebAuthn in your applications, you can offer users a more secure and convenient authentication experience without the need for passwords. In this blog post, we’ve covered the basics of WebAuthn, its importance, and how to set it up using a Node.js + React codebase with Fastify.
As the web continues to evolve, embracing new security standards like WebAuthn will become increasingly crucial for businesses and developers alike. By investing time and effort in understanding and implementing these technologies, you can help build a more secure and user-friendly internet for everyone.
Leave a comment
To make a comment, please send an e-mail using the button below. Your e-mail address won't be shared and will be deleted from our records after the comment is published. If you don't want your real name to be credited alongside your comment, please specify the name you would like to use. If you would like your name to link to a specific URL, please share that as well. Thank you.
Comment via email