DEV Community

Cover image for Authenticate a Nuxt.js App Using a Magic URL and Mailgun
Moronfolu Olufunke for Hackmamba

Posted on

Authenticate a Nuxt.js App Using a Magic URL and Mailgun

Authentication involves checking and ascertaining the genuineness of a user, i.e., verifying if the person trying to gain access to a product is the right person. Authentication has evolved from the traditional method of manually using passwords to using magic Uniform Resource Locators (URL).

A Magic URL is a one-time passwordless authentication URL sent to a secure destination, most times the email, from where the user can access it to log into the application. The magic URL removes the user's effort to put their password into an application manually. Instead, a securely generated link is sent to the user’s account, and opening this magic link will subsequently sign the user in to access the application.

This article will discuss how to authenticate a Nuxt application using Appwrite’s magic URL.

GitHub

Check out the complete source code here.

Prerequisites

Understanding this article requires the following:

  • Installation of Node.js
  • Basic knowledge of TypeScript
  • Docker installation
  • Basic understanding of Simple Mail Transfer Protocol (SMTP)
  • An Appwrite instance; check out this article on how to set up an instance locally or one-click install on DigitalOcean or Gitpod

Creating a Nuxt project

Use npx create-nuxt-app <project-name> to create a new Nuxt project.
The process of scaffolding the project would provide a list of options, which should look like this:
Nuxt application scaffolding options

We can start our Nuxt3 application by running the following command:

cd <project name>
npm run dev
Enter fullscreen mode Exit fullscreen mode

Nuxt will, in turn, start a hot-reloading development environment that is accessible by default at http://localhost:3000.

Installing Appwrite

To use Appwrite in our project, we will install the Appwrite web software development kit (SDK) from the command line, like so:

npm install appwrite
Enter fullscreen mode Exit fullscreen mode

Creating an Appwrite project

To create a new project, start up the Appwrite instance on your machine and navigate to the specified hostname and port http://localhost:80. Next, we need to log in to our account or create an account if we don’t have one.

Appwrite Create a project interface

The project dashboard becomes visible on the console after the project creation. We can access the inner page from the Settings tab at the top of the page.

The magic URL settings annotation

The inner page allows us to copy the Project ID and API Endpoint for use in our Nuxt application.

The project and API endpoint page of the created project on the Appwrite console

We will then proceed to create an init.js file in our Nuxt application’s root directory to initialize the Appwrite Web SDK by adding the code block below:

import { Client, Account } from "appwrite";
export const client = new Client();
export const account = new Account(client);
client
  .setEndpoint('http://localhost/v1') // Your API Endpoint
  .setProject('***') // Your project ID
;
Enter fullscreen mode Exit fullscreen mode

Setting up Mailgun as an SMTP

Simple Mail Transfer Protocol (SMTP) is a protocol, sometimes referred to as an application used in sending and receiving emails. There are several SMTP services like SendGrid and Mailgun, but in this article, we will use Mailgun - Appwrite also supports other emailing services.

We will start by creating an account with Mailgun. We can then log into our Mailgun dashboard to get hold of our credentials for usage on Appwrite. From our dashboard, we will navigate to Sending > Overview, from where we can select SMTP as seen below:

Annotations showing how to navigate Mailgun dashboard to get credentials

Clicking on SMTP brings the Mailgun credentials as shown below:

The SMTP credentials on Mailgun

We take note of these credentials as we need them in Appwrite.

Updating our Appwrite .env with Mailgun credentials

Installing Appwrite on our computer makes a docker.comopose.yml and a .env environment file available, as seen below:

The .env and docker-compose files in the installed Appwrite folder on our computer

We are at liberty to customize the .env to meet our server needs. To use Mailgun SMTP, we will need to update some properties within the Appwrite env, like so:

_APP_SYSTEM_EMAIL_NAME=Name
_APP_SYSTEM_EMAIL_ADDRESS=example@outlook.com
_APP_SMTP_HOST=smtp.mailgun.org
_APP_SMTP_PORT=587
_APP_SMTP_SECURE=tls
_APP_SMTP_USERNAME=postmaster@sandbox2a88e2********b40.mailgun.org
_APP_SMTP_PASSWORD=f13cd0*******e93193
Enter fullscreen mode Exit fullscreen mode

_APP_SYSTEM_EMAIL_NAME=Name : Denotes senders’ name

_APP_SYSTEM_EMAIL_ADDRESS : Refers to senders’ email addresses.

_APP_SMTP_HOST : The SMTP hostname, which in this case is smtp.mailgun.org

_APP_SMTP_PORT : SMTP Transmission Control Protocol (TCP) port represented as 587

_APP_SMTP_SECURE : Represented with tls to denote the SMTP connection protocol

_APP_SMTP_USERNAME : SMTP’s username

_APP_SMTP_PASSWORD : SMTP password

After setting the above and saving our file, we will need to restart our Appwrite container using the command below in our terminal, after navigating into the folder that contains the docker-compose file:

cd Appwrite // navigate into the Appwrite folder
docker-compose up -d --remove-orphans
Enter fullscreen mode Exit fullscreen mode

With this done, we can navigate to our Appwrite console to add a new platform to use magic URL on Appwrite.

Adding the magic URL platform on Appwrite console

To use Appwrite’s magic URL service, we will need to add a new platform within the Appwrite application we have created. To do this, we will navigate to the project we want to use the magic URL. We will then create a New Web App platform like so:

Annotated option selected for creating a platform for a web app

We will add a distinct name for the platform with a hostname.

The create platform form on Appwrite console

The hostname represents the Appwrite domain added during the Appwrite installation - in our case, localhost was used like so:

_APP_DOMAIN=localhost
_APP_DOMAIN_TARGET=localhost
Enter fullscreen mode Exit fullscreen mode

The domain name used depends on what we set in the .env file, and this domain should always match the base URL of the application.

Getting the magic URL

Now we are ready to begin building our application. To do this, we will navigate into our application’s pages/index.vue and edit the file to the code below:

<template>
  <div class="bg-lightest-blue vh-100 pa3 tc">
    <h2 class="ttc">Magic URL with Appwrite</h2>
    <div class="br3 bg-navy ba near-white b--black-10 shadow-3 w-100 w-60-m w-30-l mw6 center mt5 ph4 pv4 h5">
      <p class="f3">Click on this button to get the magic URL</p>
        <button class="link br3 pv2 ph2 mt4 dib black fw6 bg-white ba b--navy pointer inline-flex items-center hover-bg-lightest-blue" @click="sendMagicURL">
          <span class="f4 ml2 pr2">Get magic URL</span>
        </button>
    </div>
  </div>
</template>

<script lang="ts">

import Vue from 'vue'
import {account} from '~/init'
import { ID } from 'appwrite';

export default Vue.extend({
  name: 'IndexPage',
  methods: {
    sendMagicURL: async function () {
      try {
        await account.createMagicURLSession(ID.unique(), 'example@email.com', 'http://localhost:3000/verify')
        alert('Magic URL sent')
      } catch (error) {
        console.log(error)
      }
    }
  }
})
</script>
Enter fullscreen mode Exit fullscreen mode

The code snippet above performs the following functions:

  • We added a button in our <template>, which calls the sendMagicURL function within our methods object
  • The sendMagicURL function access the createMagicURLSession on Appwrite’s account method
  • The createMagicURLSession takes in two required parameters:
    • userId: A unique Id is gotten by accessing Appwrite’s ID method.
    • email: The email we would like to send the magic URL to
  • The third optional parameter in the createMagicURLSession function is the URL we would like to redirect the user to after clicking on the magic URL. This URL must be the hostname added to our Appwrite project platform.

At this point, we will have an email in our inbox that will expire in an hour. Our pages/index.value will also look like the below:

The home page

Verifying the magic URL

The magic URL sent to the email address added will have a userId and secret key for creating a session, which we will access to complete our login process. To do this, we will create a new file named pages/verify.vue, which the user gets redirected to after clicking the email in the inbox. We will edit the page by adding the code below:

<template>
  <div class="bg-lightest-blue vh-100 pa3 tc">
    <h2 class="ttc">Magic URL with Appwrite</h2>
    <div class="br3 bg-navy ba near-white b--black-10 shadow-3 w-100 w-60-m w-30-l mw6 center mt5 ph4 pv3 h5">
      <p class="f3">Verify Magic URL</p>
      <p>To complete this session, please verify your magic URL by clicking the verification button.</p>
        <button class="link br3 pv2 ph2 mt3 dib black fw6 bg-white ba b--navy pointer inline-flex items-center hover-bg-lightest-blue" @click="verifyMagicURL">
          <span class="f4 ml2 pr2">Verify magic URL</span>
        </button>
    </div>
  </div>
</template>
<script lang="ts">

  import Vue from 'vue'
  import {account} from '~/init'

  export default Vue.extend({
    methods: {
      verifyMagicURL: async function ()  {
        const urlParams = new URLSearchParams(window.location.search);
        const userId : any = urlParams.get('userId');
        const secret : any = urlParams.get('secret');
        try {
          await account.updateMagicURLSession(userId, secret);
          alert("Magic URL verified")
          window.location.href = '/landing'
        } catch (err){
          console.log(err)
        }
      }
    }
  })
</script>
Enter fullscreen mode Exit fullscreen mode

From the code snippet above, we were able to verify our account by doing the following:

  • Added a verifyMagicURL function within our methods which creates a new URLSearchParams object which returns a URL querying string
  • Returned the values of the userId and secret using urlParams.get() method
  • Accessed the updateMagicURLSessionon Appwrite’s account method, which takes in the values of the userId and secret
  • Redirected our application to the landing page represented with /landing after successful verification

Our pages/verify.vue will look like the below before verification:

The verification page UI

Creating the landing page

After successfully verifying the magic URL, we will redirect the user to a landing page. To achieve this, we will create a pages/landing.vue and add the code below:

<template>
  <div class="bg-lightest-blue vh-100 pa3 tc">
    <h2 class="ttc">Magic URL with Appwrite</h2>
    <div class="br3 bg-navy ba near-white b--black-10 shadow-3 w-100 w-60-m w-30-l mw6 center mt5 ph4 pv3 ">
      <p class="f2">Verification successful 🎉🎉</p>
      <p></p>
    </div>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

At this point, our landing page will look like the below:

The landing page UI

We have successfully implemented a Magic URL login using Appwrite, and our application will look like the gif below:

Our final implementation

Conclusion

One of the fantastic features Appwrite provides is the magic URL that simplifies authentication for users without the hassle of the user trying to remember their passwords. This post discusses how to implement the magic URL during authentication.

These resources might be helpful:

Top comments (1)

Collapse
 
kissu profile image
Konstantin BIFERT

Clear and precise, thanks! 🙏🏻