Send magic links using Node.js
The most popular method of entering the application is to provide a username and password, but users can find certain disadvantages in this. Although there are many password managers, using them takes time. Not much, but still. Some applications promote a complex and thereby disappointing password policy, so coming up with a new password can be tricky. A passwordless system can be a good alternative to conventional authentication by login and password. It is used by Slack and FramerX, and it looks like sending a magic link to the user to enable such authentication in the application. A passwordless system works as follows:
- The user visits the application, where there is a form for entering an email address;
- The user enters an email address and presses the confirmation button;
- A magic link to enter the system is sent to the user’s email;
- The user clicks on the link and is redirected to the application where he has already logged in.
After that, the magic link is no longer valid.
Below we will look at some key points for implementing passwordless authorization on Node.js.
Create express – attachment
To get started, we need to create a simple express application and add some endpoints. The code below is responsible for setting up an express server with helpers for parsing incoming requests, login and adding cors. We will need to create two directories to which we will add handlers later. It will be /login
and /account
. The first handler will be responsible for sending magic links to users, and the second – for their authentication.
server.ts
Configure nodemailer
We will use nodemailer to send emails, but first you need to configure it. We will need several components: an email address, an email password, an SMTP server host, and an SMTP server port. We will also need a letter template, which we will send to users with a magic link. A template can be just a string or an HTML page.
Token Generation
For this we will use the package jsonwebtokenwho as a whole will do everything for us. Our token will consist of two properties: email address and expiration time.
token.ts
Email sending
Now we need to add a login handler, where we will first verify that the request contains the user’s email address, then generate a new token for this specific user and, finally, use the mechanism described in the code above to send the email.
User authentication
When a user logs on to the system, we need to authorize his requests to our server. To do this, do the following:
- Check if there is an authorization header in the request;
- Verify that the authorization header is
bearer token
; - Try to decode this token;
- Check that the token has all the required fields. In our case:
email
andexpiration
. - Compare the date and time from expiration with the current ones to verify that the token has not expired.
- Finally, verify that the user with the email retrieved from the token exists.
Conclusion
Here’s the basic setup for passwordless login on top of a normal authorization stream. The biggest advantage that I see in this approach is that if users can log in to a product faster and easier, their experience with using the product will improve.
On the other hand, even if logging into the system can be easier than with a regular login / password, then returning to it can be more difficult. Each time a user logs in, he will need to wait for an email, check his inbox and click on the link. This process can also be unpleasant, so if a session has short periods of timeout or it is expected that users will often log into the system, then passwordless authorization may not be the best choice.