next.jsazure-active-directorynext-auth

How do I display Job Title in my Next Auth app


How do I display Job Title and other user properties in my Next Auth app using Azure AD / Entra ID.

I am using next-auth v5 and Next.js V14 so I have an app directory and no pages directory.

This is my route.tsx (placed in [...nextauth]/):

import NextAuth from "next-auth";
import { options } from "./options";

export const {
    handlers: { GET, POST },
    auth,
    signIn,
    signOut,
  } = NextAuth(options);

this is my options.tsx:

import type { NextAuthOptions } from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";

export const options: NextAuthOptions = {
    providers: [
        AzureADProvider({
            clientId: process.env.AZURE_AD_CLIENT_ID,
            clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
            tenantId: process.env.AZURE_AD_TENANT_ID,
        }),
    ],
}

and this is my page.tsx:

import { auth, signOut } from "./api/auth/[...nextauth]/route"

function SignOut() {
  return (
    <form action={async () => {
      'use server';
      await signOut()
    }}>
      <button type="submit">Sign out</button>
    </form>
  )
}

export default async function Home() {
  const session = await auth();
  return (
    <>
      {session?.user ? (
        <div>
          <p>Welcome {session.user.name}!</p>
          <div><SignOut /></div>
        </div>
      ) : (
        <div>
          <p>You are signed out!</p>
          <a href="/api/auth/signin"><button>Sign in</button></a>
        </div>
      )}
    </>
  );
}

Please help me. Thanks in advance!


Solution

  • This works

    In your options.tsx add this:

    providers: [
        AzureADProvider({
          clientId: process.env.AZURE_AD_CLIENT_ID,
          clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
          tenantId: process.env.AZURE_AD_TENANT_ID,
        })
      ],
      callbacks: {
        jwt({ token, account }) {
          if (account){
            token.accessToken = account.access_token;
          }
          return token;
        },
        async session({ session, token }) {
          if (token.accessToken) {
            try {
              const response = await axios.get('https://graph.microsoft.com/v1.0/me?$select=jobTitle', {
                headers: {
                  Authorization: `Bearer ${token.accessToken}`,
                },
              });
              session.user.jobTitle = response.data.jobTitle;
            } catch (error) {
              console.error('Error fetching job title from Microsoft Graph API:', error);
            }
          }
          return session;
        },
      }
    

    now you can use in your script as session.user.jobTitle