17 May 2023 · Software Engineering

    Developer’s Guide to Passwordless Authentication

    12 min read
    Contents

    Recently, the use of passwordless authentication has been rising in popularity among developers. The driving factor for this is that it is more secure and convenient than password-based authentication.

    Password-based authentication systems are vulnerable to cyber attacks such as brute-force attacks. To prevent cyber crimes, users must often change their passwords and use difficult-to-guess passwords. Many users may find this to be inconvenient, as they are not good at creating strong passwords.

    According to NIST, frequently changing passwords is no longer recommended. As users choose passwords typically relate to their previous passwords and those that are easy to remember. Such passwords are primarily weak and less secure.

    Developers must provide a secure account verification architecture to avoid inconveniences and security risks. That’s where passwordless authentication comes into play.

    Passwordless authentication is any identity verification method that doesn’t use a password. Getting an in-depth understanding before committing to the approach would be great. This article aims to take you through passwordless authentication and its implementation.

    What is passwordless authentication?

    Passwordless authentication is a more convenient way to log in. It is a verification method that enables users to access applications, systems, and networks without a password. Enterprises and individuals shifting to passwordless authentication is a digital transformation. Thanks to passwordless authentication, passwords are no longer necessary.

    Passwordless authentication doesn’t require any particular technology or procedure to verify a user’s identity. It is more of a goal attained by employing various strategies or solutions. Passwordless authentication is frequently used with biometrics, authenticator applications, one-time passcodes (OTP) transmitted by emails or SMS, etc. Passwordless authentication solutions ensure a seamless user experience, improve data security, and lower IT operations costs and complexity.

    Passwordless security

    Passwordless authentication is more secure than password-based authentication. Secure, in this case, means that the authentication method is less prone to hacking and cyber-attacks. Still, passwordless authentication methods may be vulnerable in one way or another and, thus, are not 100% safe. There may not be an obvious way to hack them, but the most skilled hackers can find a way to get past safety measures, given enough time and effort.

    Employing passwordless authentication methods will prevent attacks such as phishing and brute force attacks. Biometric authentication, for instance, offers the highest level of security of any form of authentication. Using biometrics to verify a user’s identity is far more secure than passwords. This makes passwordless authentication hard to beat in terms of security.

    Hackers don’t execute complex database attacks to get the user’s credentials. They use social engineering techniques and phishing to steal usernames and passwords. As a result, passwords are the most common target for cybercriminals. Getting rid of them leaves hackers with nothing to steal or manipulate.

    To keep passwordless authentication more secure, you can utilize Multi-factor authentication (MFA). MFA provides a more secure way of maintaining the applications, systems, and network.

    Passwordless authentication methods

    Passwordless authentication is a much more secure and effective way to secure your accounts. This section will break down each authentication method to understand how they can help keep your data safe.

    Single Sign-On (SSO)

    SSO is the most common method of passwordless authentication. It enables users to securely log into third-party applications using a single set of credentials. Almost everyone has logged in using Google, Facebook, Slack, and more via SSO.

    SSO prevents users from having to repeatedly authenticate each time they are disconnected from accessing a particular service. Users find this quite convenient as they can retain a valid session on all SSO-enabled applications by identifying themselves once.

    Biometrics

    Biometric authentication verifies a user’s identity using physical or behavioral characteristics. The biological factors include:

    • Fingerprint recognition
    • Facial recognition
    • Voice recognition
    • Iris scan

    To set up an account, the user must choose one or more of the above physical characteristics, which are then stored in a database. To access the account, the user’s characteristics are compared with the details stored in the database. Verification occurs when the match succeeds and the user is logged into the account.

    Biometric identification is used to simplify a user’s experience with systems. The method is more secure because the probability of identical fingerprints, face, or iris is very low. Various types of applications and devices that are security conscious such as those related to banking, schools, health sectors, mobile phones, and more, use biometric authentication methods to authenticate.

    Possession factors

    Possession factors grant access to users via something they own/possess, such as a mobile device. Users can receive a one-time passcode (OTP) via email or SMS. Users then get logged into the system automatically by responding to notifications or entering the codes.

    Cyberattacks are less likely to occur in this instance because cybercriminals need the relevant possession factor to respond to application’s requests.

    Magic links allow users to authenticate without a password. The user is prompted to input their email address. The system then sends a one-time URL to the email. Once the URL is opened, the user can log in to the application or account.

    Magic links are intuitive and provide a great user experience during authentication. After all, clicking a link and getting direct login to an application is more straightforward than typing a username and password.

    Benefits of passwordless authentication

    Enhanced user experience

    According to research by Nordpass, the average person has 70 to 80 passwords. Therefore, it would take the average person a lot of work to create so many complicated passwords. Remembering different complex passwords is also a challenging task. Furthermore, resetting the passwords is a hassle, as much time is wasted. People must go through these inconveniences to log into various applications and keep their accounts secure.

    Passwordless authentication provides users with a hassle-free experience. Users can receive an OTP via SMS or email, enter the code, and directly access their account. Biometric authentication requires physical characteristics, i.e. fingerprint or face, to verify and get access to applications. This method is quite secure as physical characteristics are unique in almost all cases. Passwordless authentication improves the user experience because it is fast, efficient, and safe.

    Reduced costs and maintenance

    Passwordless authentication reduces security costs. An organization doesn’t have to spend on password storage systems, management, maintenance, and resets. This saves the IT support department a lot of time and effort because they won’t have to deal with password reset, password recovery, and dealing with lost passwords when a cyber attack occurs. Moreover, theIT team won’t have to find and prevent password breaches.

    Passwordless authentication makes it possible to decrease or completely remove the cost of handling password-based security-related concerns. Companies can save millions of dollars by doing away with password-based security and associated password management.

    Improved security

    Passwords are easily cracked and guessed. Phishing and brute force attacks are the most common methods used to steal passwords. In research done by the Ponemon Institute, companies lose an average of $3.92 million from data breaches. If cybercriminals can get your passwords, it means they are also able to access sensitive company data. Once they have access, they can do what they want with a company’s data.

    Passwords are more vulnerable to attacks, and passwordless authentication methods dramatically improve security and reduce data breaches.

    Challenges in passwordless authentication

    Cost of deployment

    Passwordless authentication is secure and enhances the user experience. The challenge comes during deployment. You need an in-depth plan during passwordless authentication implementation. Deploying passwordless authentication in organizations attract extra costs. Users may need training, and new software and hardware.

    Accepting change

    Many people fear change. Some people may be reluctant to do away with the password-based authentication method and try the passwordless authentication method because of this. This requires effort on the part of the organization to overcome, but it’s worth it.

    Security constraints in passwordless authentication

    Passwordless authentication is not 100% secure. Cybercriminals may use malicious methods such as malware and trojans to breach the security of a system or application. Developers should use strong security measures to avoid cyber attacks. Accordingly, organizations should also use MFA with different levels of security.

    Passwordless authentication in practice with Node.js

    To demonstrate passwordless authentication in practice with Node.js. You will need a basic understanding of HTML and JavaScript to create a front end. Also, you will need Node.js installed on your device.

    • You will create a form that collects the user’s email address on the login page.
    • When the users enter and send their email addresses. A magic link is sent. The Node.js server should generate a unique token and send it to the user’s email address along with the link to the login page.
    • When the user clicks the link, the server verifies if the token is valid.
    • If the token is valid, the server sets a session for the user. Finally, the user gets redirected to the application.

    Here is the implementation of passwordless authentication using HTML, JavaScript, and Node.js.

    Create an HTML form index.html that uses an index.js file.

    <!DOCTYPE html>
    <html>
        <head>
            <title>Passwordless Authentication</title>
        </head>
        <body>
            <h1>Enter your email and get a magic link.</h1>
            <p id="info"></p>
            <form>
                <div>
                    <label for="email_address">Enter your email address</label>
                    <input type="email" id="email_address" placeholder="Enter Email Address" />
                </div>
                <button type="button" id="send_email">Get magic link</button>
            </form>
            <script src="index.js"></script>
        </body>
    </html>
    index.js:
      const submitButton = document.getElementById("send_email");
      const emailInput = document.getElementById("email_address");
      let emailValue = '';
      emailInput.addEventListener('change', e => {
        emailValue = e.target.value;
      });
      submitButton.addEventListener("click", handleAuth);
      /** This function sends a request to the server and sends a magic link to the user.*/
    
      async function handleAuth() {
        console.log("emailvalue",emailValue);
        try{
          let message = await fetch('http://localhost:3000/send_magic_link',{
            method:"POST",
            body:JSON.stringify({
              email: emailValue
            }),
            headers:{
              "Content-Type":"application/json"
            }
          });
          message = await message.json();
          console.log("message ",message);
          document.getElementById("info").innerHTML = "Magic link successfully sent!! Hurray!!!";
        }catch(error){
          document.getElementById("info").innerHTML = "Ooh no! Magic link not sent successfully";
        } 
      }

    Node.js server setup

    In this section, you’ll set up the Node.js server. Name the server app.js, also have a .env file that stores the users credentials.

    .env
    EMAIL_HOST="smtp.gmail.com" 
    EMAIL_USER="your_gmail"
    EMAIL_PASSWORD="your_gmail_password"
    SECRET="your_secret_key"

    You’ll begin by creating an express application and installing a few packages. The packages include express, body-parser, cors, nodemailer, jsonwebtoken.

    const PORT = process.env.PORT || 3000;
    
    const express = require('express');
    const bodyParser = require('body-parser');
    const cors = require('cors');
    const nodeMailer = require('nodemailer');
    const jwt = require ('jsonwebtoken');
    const session = require('express-session');
    require("dotenv").config();
    
    const app = express();
    
    app.use(cors());
    app.use(bodyParser.json());
    
    app.set('trust proxy', 1) // trust first proxy
    app.use(session({secret: 'mySecret', resave: false, saveUninitialized: false}));

    The installed packages allow us to handle incoming requests, parse data, and send emails. Because you installed the nodemailer, you will create a transporter to send magic links.

    const transport = nodeMailer.createTransport({
        service: 'gmail',
        host: process.env.EMAIL_HOST,
        port: 587,
        auth: {
            user: process.env.EMAIL_USER,
            pass: process.env.EMAIL_PASSWORD
        }
    });

    Generating tokens

    When the server receives the email address, It should generate a unique token and store it in a database. The token holds the user’s information, then authenticates the user.

    //Generating a token
      const makeToken = (email) => {
        const expirationDate = new Date();
        expirationDate.setHours(new Date().getHours() + 1);
        return jwt.sign({ email, expirationDate },process.env.SECRET);
    };

    Users should be authenticated and logged in to the app immediately when they click the link.

    // Create email template for magic link
    const emailTemplate = ({ username, link }) => `
        <h2>Hey ${username}</h2>
        <p>Here's the magic link you requested:</p>
        <p>${link}</p>
    `;
    
    app.post("/send_magic_link", function (req, res) {
        const { email } = req.body;
        if (!email) {
          res.status(403);
          res.send({
            message: "Invalid email address.",
          });
        }
        const token = makeToken(email);
        const mailOptions = {
          from:process.env.EMAIL_USER,
          html: emailTemplate({
            username: email,
            link: `http://localhost:3000/authenticate_user?token=${token}`,
          }),
          subject: "Your Magic Link",
          to: email,
        };
        return transport.sendMail(mailOptions, (error) =>{
          if (error) {
            console.log("error ",error);
            res.status(403);
            res.send("Can't send email.");
          } else {
            res.status(200);
            res.send(`Magic link sent. : http://localhost:3000/authenticate_user?token=${token}`);
          }
        });
    });

    Next, we will need an authentication method. The authentication method is called once the token is taken from the front end.

    const isAuthenticated = (req, res) => {  
        
        const { token } = req.query
        if (!token) {
            res.status(403)
            res.send("Can't verify user.")
            return
        }
        let decoded = "";
        try {
            decoded = jwt.verify(token, process.env.SECRET);
        }
        catch {
            res.status(403)
            res.send("Invalid auth credentials.")
            return
        }
        if (!decoded.hasOwnProperty("email") || !decoded.hasOwnProperty("expirationDate")) {
            res.status(403)
            res.send("Invalid auth credentials.")
            return
        }
        const { expirationDate,email } = decoded
        console.log("decoded ",decoded);
        if (expirationDate < new Date()) {
            res.status(403)
            res.send("Token has expired.")
            return;
        }
        req.session.email = email;
        res.status(200)
        return res.redirect('http://localhost:3000/welcome');
    }
    
    app.get('/authenticate_user', (req, res) => {
        isAuthenticated(req, res);
    });
    
    app.get('/welcome', (req, res) => {
      return res.status(200).send(
        "You are logged in! as "+req.session.email
      );
    });
    
    const server = app.listen(PORT, () => {
        console.log(`Server running on port ${server.address().port}`);
    });

    When the user clicks the link sent via email, the server should be able to verify the token. This involves comparing it with the secret code in the database. If the tokens match, the user gets authenticated by decoding it using the secret key that created it. If tokens do not match, the system returns an error.

    Wrapping up

    Password-based login systems are vulnerable and insecure. Migrating to passwordless authentication improves the organization’s user experience, security, and workforce productivity.

    Passwordless authentication saves time and costs. Implementing and executing passwordless authentication will cost less than losses from data breaches.

    To summarize, you have learned the following;

    • What passwordless authentication is
    • Methods of passwordless authentication
    • Benefits and challenges of passwordless authentication
    • Passwordless authentication in practice with Node.js

    That’s it for this overview of passwordless authentication. Happy learning!

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Avatar
    Writen by:
    Judy is a Web developer, passionate about technical writing. She is not hesitant to step out of her comfort zone and explore new programming development methodologies and technologies.
    Avatar
    Reviewed by:
    I picked up most of my skills during the years I worked at IBM. Was a DBA, developer, and cloud engineer for a time. After that, I went into freelancing, where I found the passion for writing. Now, I'm a full-time writer at Semaphore.