Two Factor Authentication
In this post we're going to cover adding two factor authentication to a Meteor application. I recently discovered a distinct lack of packages (none?) that provided this functionality so I created one! You can find it here: https://github.com/dburles/meteor-two-factor.
If you're not sure what two factor auth is exactly, this wikipedia article explains in detail what it's all about.
A couple of diagrams
Let's illustrate both regular and typical two factor authentication flow.
Regular authentication
Pretty self explanatory.
Two factor authentication
Two factor authentication (as the name implies) requires an extra factor in authenticating with the application.
Implementation
The code examples we'll use throughout the rest of the article will be borrowed from this example app.
Step 1
First, add both accounts-password
and dburles:two-factor
packages:
$ meteor add accounts-password dburles:two-factor
Step 2
If you're adding two factor support to an existing application, replace Meteor.loginWithPassword with twoFactor.getAuthCode. Both functions are called identically.
Template.login.events({
'submit form'(event, template) {
event.preventDefault();
const user = template.$('#user').val();
const password = template.$('#password').val();
twoFactor.getAuthCode(user, password, error => {
if (error) {
return Session.set('loginError', error.reason);
}
Session.set('loginError', '');
});
}
});
After valid credentials have been passed in, the package will (by default) generate a 6 digit code that must be used in order to sign in.
Step 3
We use the reactive isVerifying function to display the verification code form. If it returns true
; display the form (if you don't have one, make one!).
Template.body.helpers({
isVerifying() {
return twoFactor.isVerifying();
}
});
Step 4
Now we can capture the verification code and pass it to verifyAndLogin.
Template.verify.events({
'submit form'(event, template) {
event.preventDefault();
const code = template.$('#code').val();
twoFactor.verifyAndLogin(code, error => {
if (error) {
return Session.set('verifyError', error.reason);
}
Session.set('verifyError', '');
});
}
});
Step 5 – Server side
We need a way to actually get the code to the user. For that, we'll define a function called sendCode. For the sake of the example we'll just log it to the terminal, in the real world this might send an SMS or an email. Make sure you define this only on the server.
twoFactor.sendCode = (user, code) => {
console.log(`Authentication code for '${user.username}' user is: ${code}`);
};
Conclusion
That's it!, there's a few more functions that we didn't cover here, you can find them documented on GitHub.
Just a random side note, I've received a lot of feedback on the blog with comments such as: "You can explain complex things in simple words :)". I really appreciate that! I always endeavour to write with brevity and clarity.
Thanks for reading!
Resources
Two factor package
https://github.com/dburles/meteor-two-factor
Example application
https://github.com/dburles/two-factor-example