Add Magic Link logins to your ExpressJS app

Magic links are a win-win when it comes to both security and user experience. This is why it's no surprise that companies like Slack and Medium are using them to authenticate their users. For a deeper comparison of magic links and other authentication methods, check out our post on magic links and the future of password-less.

Convinced? Great, let's get started on moving your site to the forefront of authentication.

How to use ApproveAPI for magic links

ApproveAPI has a PassportJS strategy that uses ApproveAPI prompts to send secure magic links to users. PassportJS is the standard authentication middleware for ExpressJS, so if your application doesn’t already have it you will need to:

npm install passport

Then, to install our magic link strategy run:

npm install passport-approveapi

Additionally, it is extremely likely that you will want to have persistent authentication sessions for your web application, so it is recommended that you configure a session manager, such as express-session.

Now that the necessary packages are installed, you can import and initialize them at the top level of your application using the following codeblock:

var passport = require('passport');
var ApproveAPIStrategy = require('passport-approveapi').Strategy;
passport.use(new ApproveAPIStrategy({
	apiKey: 'YOUR_APPROVEAPI_KEY',
	callbackUrl: 'https://your.website/auth/callback',
	contactField: 'email',
	promptMessage: 'Log in to your account on Acme Website?',
}, verifyUser));
app.use(passport.initialize());
app.use(passport.session());

Then you need to define routes for requesting and accepting magic-link tokens. Here’s an example of how to do that:

app.post('/auth/approveapi',
	passport.authenticate('approveapi', {action: 'requestToken'}),
	(req,res) => res.redirect('/check-your-email')
);

app.get('/auth/approveapi/callback',
	passport.authenticate('approveapi', {action: 'acceptToken'}),
	(req,res) => res.redirect('/')
);

The path that you use for the acceptToken action needs to be the same as the callbackUrl parameter, because that is where the user’s magic-link tokens will be sent after they approve the magic-link.

For the strategy initialization, verifyUser is a function that takes as input a user Object, which contains whatever was posted to the requestToken route, and either returns a valid user object as a result of that input (if the data POSTed by the user corresponds to a valid user), or throws an Error if the data is invalid (malformed, bad user, etc). If a valid user object is returned, the magic link is sent which, when clicked, authenticates that valid user. If an Error is thrown, the authentication is stopped. verifyUser is up to you to implement to fit your user model.

The other parameters are:

  • apiKey: your ApproveAPI key, found on the ApproveAPI Dashboard .
  • callbackUrl: a complete URL to your acceptToken route, which must be prepended with 'https://'.
  • contactField: the property path for the user’s email in your valid user object. This is where the magic-link gets sent.
  • promptMessage: the message accompanying the ApproveAPI prompt in the magic-link email.
  • ttl: an optional parameter defining how long the magic-links are valid for. Defaults to 10 minutes.

For all secured application routes, you can check that PassportJS’s req.user field is set correctly, as with any other PassportJS strategy. The req.user field is populated once a valid magic-link is followed.

Your application should now be ready to conveniently handle authentication using magic links!