Abra-QR-dabra: Watch Passwordless Mobile Auth Magically Appear
Tags: webdev, javascript, tutorial, react
Published: 2023-06-01 23:27:48

A few days ago, a [post on hacker news](https://news.ycombinator.com/item?id=36128082) caught my eye, where folks were playing around with and linking to various QR Code designers. This got me to thinking, how quickly could I add a QR flow into our authentication processes?

#### Starting Out

For ease and speed, I wanted to work with a preexisting application to see how quickly I could slot this feature in, without needing to spend time with setup. To that end, I started up our [React/Express Starter Application](https://www.propelauth.com/post/react-express-starter-app) as a base. Reminder, this is how the application looks at the end of our starter guide:


![Result of the starter guide](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nb8cy5sdm8soayejf0od.png)

In terms of flow for the application, I thought about a kind of product that requires some version of mobile interaction after setting up an account on the browser. Think of a product like [PagerDuty](https://www.pagerduty.com/?ref=propelauth.com), which is used to send alerts when issues arise. Most customers that are configuring PagerDuty are going to use their desktop to set up their on-call schedule, generate API keys, etc.

However, an important step in the process is setting up your phone, for use cases like adding PagerDuty’s phone numbers to the exceptions to your DND settings. So one way to move customers from their desktop to their phones is to send them a magic link, which we can put in a QR code.


![Basic QR code example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l633ryj9v7z6vtyeo6mo.png)

So the expected flow for this use case would be:

* The user is already logged in on their laptop/desktop
    
* The user needs to be logged in on their mobile device
    
* We generate a magic link on the backend and return it to the browser
    
* We render that as a QR code so the user can easily sign in on their mobile device
    
* (Optional) We can direct them to a specific page so they are dropped in to the product exactly where they need to be
    

To begin, I set up another route for the page that would display the QR code, and built that component, called **qr.jsx**. Next, I installed a [React friendly QR code generator](https://www.npmjs.com/package/qrcode.react)

```plaintext
npm install qrcode.react
```

In the new component, I wrote a fetching function that would reach out to a new endpoint, `‘/generate-mobile-login-link’`. Next, the component calls this function, and renders the response as a QR code generated from the library we imported.

```javascript
import { withRequiredAuthInfo} from "@propelauth/react";
import { QRCodeSVG } from 'qrcode.react';
import { useEffect, useState } from "react";

function fecthNewLink(accessToken) {
	return fetch(`/generate-mobile-login-link`, {
		headers: {
			"Content-Type": "application/json",
			"Authorization": `Bearer ${accessToken}`
		}
	}).then(response => {
		console.log('response in fetch: ', response)
		if (response.ok) {
			return response.json()
		} else {
			return {status: response.status}
		}
	})
}

function QR({ accessToken }) {
	const [response, setResponse] = useState(null)

	useEffect(() => {
		fecthNewLink(accessToken).then(setResponse)
	}, [accessToken])

	if (response) {
		return <div>
			<QRCodeSVG value={JSON.stringify(response.newLink)} />
		</div>
	} else {
		return <div>Loading...</div>
	}
}

export default withRequiredAuthInfo(QR);
```

#### Creating a Magic Link

We have [an endpoint in our backend client libraries](https://docs.propelauth.com/reference/backend-apis/express#create-magic-link) that will take in a user’s email, along with a few other optional parameters, and produce a Magic Link for passwordless login.

So in order to produce this link, I added the new `/generate-mobile-login-link` route that I’m pointing to on my frontend, and used the `createMagicLink` function to pass this new URL back as a successful response. `requireUser` checks the token in the request to make sure it was made by a valid user, and then the new magic link is sent back in JSON.

```javascript
app.get('/generate-mobile-login-link', requireUser, async (req, res) => {
	let newLink = await createMagicLink({
		email: req.user.email
	})

	res.json({ newLink: newLink})
})
```

#### How Does It Work?

Pretty well! You can see the new page below making successful calls to the server.


![The page and the console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lef8fsv6ws65wf7wn8uc.png)

Granted, this is the MVP version of this kind of authentication flow. For a real product you might want to put this in a modal or as part of your onboarding flow.

That said, one optional parameter for the `createMagicLink` function is another URL to redirect to after the user is logged in, so in a production ready application I could be forwarding my users to additional setup or permissions pages.

I could also get much fancier with it! The mini project was inspired by QR code designers, so I could work in libraries like the ones mentioned in the hacker news post.


![Fancier QR code that says PropelAuth](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oa32av8q6qmf5qwprjlq.png)

Or, go even wilder, using [Halftone QR Codes](http://vecg.cs.ucl.ac.uk/Projects/SmartGeometry/halftone_QR/halftoneQR_sigga13.html) like you can see here:


![QR code with man's face](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1r1canhuv2jloye3sv8.png)

All in all, this was a fun exercise in working with our client libraries in ways that let me customize an authentication experience even more. We already offer easy passwordless login options via our hosted login pages, but it was fun to use the building blocks to make things more my own.