Nuxt, Auth, Azure AD··x·x

User Auth and Session Management in Nuxt with @sidebase/nuxt-auth and Azure AD OAuth 2.0

A guide on using Nuxt with @sidebase/nuxt-auth to authenticate and manage sessions with Azure AD OAuth 2.0.

Welcome

Project setup

  • Nuxt - 3.4.2
  • Sidebase/Nuxt-Auth - 0.5.0

Important Before you start, read through the main Github page of @sidebase/nuxt-auth. The documentation is great and the team is very helpful.

In this tutorial, we'll be adding Auth and Session management features in our Nuxt application and authenticate with Azure AD through @sidebase/nuxt-auth module.

Introduction

Nuxt is a meta framework built on top of Vue 3. @sidebase/nuxt-auth is an authentication module built for use with Nuxt. It's easy, fast, and secure.

The original nuxt-auth-example template can also be found on Github Or start along fresh, whatever you wish.

Creating a New Nuxt Application

Let's start by creating a new Nuxt application. We can create a Nuxt application using the following command:

npx nuxi init nuxt-auth-azure-ad

The above command will ask for the name of the project. We'll call it nuxt-auth-azure-ad.

Once the setup of the project and installing all dependencies are complete, we can go inside the frontend directory and start the application using the following command:

cd nuxt-auth-azure-ad && yarn dev

The above command will start the application on http://localhost:3000/.

This article won't be covering the installation of TailwindCSS. Here is a link to the official TailwindCSS docs for Nuxt to help you install and configure that part yourself.

Installing and Integrating @sidebase/nuxt-auth with Nuxt and Azure AD

In this section, we'll be installing and integrating Nuxt-Auth.

  1. Install the package
yarn add --dev @sidebase/nuxt-auth
// or 
npm i -D @sidebase/nuxt-auth
  1. Create a .env file in the root of your Nuxt project.
ORIGIN=http://localhost:3000
NUXT_SECRET=<a-better-secret>,
AZURE_AD_CLIENT_ID=<your-azure-ad-client-id>
AZURE_AD_CLIENT_SECRET=<your-azure-client-secret>
AZURE_AD_TENANT_ID=<your-azure-ad-tenant-id>
AZURE_AD_SCOPES=<your-azure-ad-app-scopes>
  1. Add the module to your nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@sidebase/nuxt-auth']
})
  1. Also add the required runtime environment variables, these are private runtime keys.
runtimeConfig: {
    private: {
        NUXT_SECRET: process.env.NUXT_SECRET,
        AZURE_AD_CLIENT_ID: process.env.AZURE_AD_CLIENT_ID,
        AZURE_AD_CLIENT_SECRET: process.env.AZURE_AD_CLIENT_SECRET,
        AZURE_AD_TENANT_ID: process.env.AZURE_AD_TENANT_ID,
        AZURE_AD_SCOPES: process.env.AZURE_AD_SCOPES
    },
    public: {}
},

Resources on where to find and get them, since you're looking for the OAuth flow for Azure AD with Nuxt, I'm assuming you already know your way around Azure. Otherwise join our discord server for help!

Azure AD - Register App

Azure AD - Scopes

  1. Configure the auth module with the following options
auth: {
    origin: process.env.ORIGIN,
    }
},

Your nuxt.config.ts file should contain the following code:

export  default  defineNuxtConfig({
  runtimeConfig: {
      private:  {
        // The private keys which are only available within server-side
        NUXT_SECRET: process.env.NUXT_SECRET,
        AZURE_AD_CLIENT_ID: process.env.AZURE_AD_CLIENT_ID,
        AZURE_AD_CLIENT_SECRET: process.env.AZURE_AD_CLIENT_SECRET,
        AZURE_AD_TENANT_ID: process.env.AZURE_AD_TENANT_ID,
        AZURE_AD_SCOPES: process.env.AZURE_AD_SCOPES,
      },
      public: {}
  },
  modules: [
    "@sidebase/nuxt-auth",
    ],
  auth: {
    origin: process.env.ORIGIN
  },
});

Make sure you have updated your .env file accordingly.

Creating and Integrating the Azure AD OAuth Flow into our Nuxt Application with sidebase

In this section, we'll use the GitHub provider and integrate it into our Nuxt application.

First off the nuxt-auth module expects all auth requests to be sent to /api/auth/*, all requests will be handled by the NuxtAuthHandler.

  1. You'll need to create a folder in the root of your Nuxt project called server, in the server folder you need to create two more folders called api and inside that auth. Structure: ./server/api/auth/
  2. We need to create a catch-all server-route that holds our NuxtAuthHandler, create a file called [...].ts in the auth folder.
  3. Copy the following logic into the newly created [...].ts file.
// ~/server/api/auth/[...].ts
import AzureADProvider from 'next-auth/providers/azure-ad'
import { NuxtAuthHandler } from "#auth";

export default NuxtAuthHandler({
  // secret needed to run nuxt-auth in production mode (used to encrypt data)
  secret: useRuntimeConfig().private.NUXT_SECRET,
  providers: [
    // @ts-ignore Import is exported on .default during SSR, so we need to call it this way. May be fixed via Vite at some point
    AzureADProvider.default({
        clientId: useRuntimeConfig().private.AZURE_AD_CLIENT_ID,
        clientSecret: useRuntimeConfig().private.AZURE_AD_CLIENT_SECRET,
        scope: useRuntimeConfig().private.AZURE_AD_SCOPES,
        tenantId: useRuntimeConfig().private.AZURE_AD_TENANT_ID,
    }),
  ]
});

The above code is an example Azure AD provider. More information here.

Sign-in Page & Auth Logic Setup

Sign-in page

In the pages folder create a new folder called auth and add a new vue page called signin.vue.

  1. Copy the following template code
<script setup lang="ts">
    const { signIn, status } = await useAuth()
</script>

<template>
  <section class="grid grid-cols-2 wrapper my-6 mx-auto items-center justify-center">
    <!-- login container -->
    <div class="bg-gray-100 flex mx-auto rounded-2xl ease-in-out duration-300 shadow-xl max-w-[60rem] p-5 items-center">

      <div class=" px-8 md:px-16">
        <h2 class="font-bold text-2xl text-[#002D74]">Login</h2>
         
         <button class="bg-[#002D74] rounded-xl text-white py-2 hover:scale-105 duration-300" @click="signIn('azure-ad', { callbackUrl: '/protected' })">
            Sign in (Azure AD)
         </button>
       
      </div>
    </div>
    
    <div class="max-w-5xl mx-auto mt-5 px-5">
        <h3 class="text-xl font-bold ">Authentication Overview</h3>
        <pre v-if="status"><span>Status:</span> {{ status }}</pre>
    </div>
  </section>
</template>

nuxt-auth generates it's own login page with matching input fields and provider styles. For this example we are using a custom sign-in page.

If you are using the original nuxt-auth-template from sidebase, redirect to one of the protected pages instead.

@click="signIn('azure-ad', { callbackUrl: '/protected' })"

However if you were following along from a clean Nuxt Application, let's move on.

Let's now create a protected dashboard area to return to after succesfully authenticating.

  1. Create a new folder within pages and call it dashboard.
  2. Inside the dashboard folder, create a new file called index.vue.
  3. Go back to your ./auth/signin.vuefile and modify the callbackUrl in the signIn() function to point to the newly created dashboard, like so:
@click="signIn('azure-ad', { callbackUrl: '/dashboard/' })"

We've set up the dashboard page structure, but nothing is actually stopping you from viewing that page. In order to do that we need to finish the article by adding the final piece. We will need to add application-side middleware.

Setting up middleware to protect the entire dashboard folder/route.

Application Side Middleware

  1. Create a folder called middleware in the root of your app.
  2. Create a file in the middleware folder called auth.global.ts and add the following code
import { defineNuxtRouteMiddleware } from  '#app'

export  default  defineNuxtRouteMiddleware(async  (to)  => {
if (to.path.startsWith('/dashboard')) {
    await useAuth({ callbackUrl: to.path })
    }
})

And there we go. That's how to get started with the Azure AD provider in Nuxt using @sidebase/nuxt-auth. You can build this example out with many more folders within the dashboard area or even protect certain components, I highly recommend checking out the awesome documentation of @sidebase/nuxt-auth. You can also find them on discord.

Change log

None yet


Services

Copyright © 2024. All rights reserved.