next-authnext.js14

How can I add the session token to every API call called from both server and client components?


I currently have Auth.js set up and working and what I am trying to do is to create a function in my API class that adds the session token to the authorization header of the request. I managed to get it to work but my issue is that it only works for server components (due to the method of Auth.js for getting the session). I need it to work both when the API is called from a server as well as a client component. When I try to call it from a client component it gives an error.

This is the code I have on my API class:

import { SessionUserType } from '@/types/auth.types';
import { auth } from '../lib/auth';

class ApiService {

    // Set Request Token

    private async setRequestToken() {
        const session = await auth();
        const user = session?.user as SessionUserType;
        let token = user?.access_token ? `Bearer ${user?.access_token}` : '';

        return token;
    }

    // Get Method

    async get(url: string) {
        const response = await fetch(url, {
            headers: {
                'Authorization': await this.setRequestToken()
            }
        });

        return this.handleResponse(response);
    }
}

The auth method comes from the auth provider I set up following the Auth.js docs:

import NextAuth from "next-auth"
import Credentials from "next-auth/providers/credentials"

import AuthService from "@/services/auth.service"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [
    Credentials({
        credentials: {
          email: {},
          password: {},
        },
        authorize: async (credentials) => {
          let data = {
            email: credentials.email as string,
            password: credentials.password as string,
          }
  
          try {
            const user = await AuthService.login(data);
            return user;
          } catch(error: any) {
            throw new Error(error?.message || error);
          }          
        },
    }),
  ],
})

What would be the way to setup the API class function so that it can get the session token when used both from server and client components?

Thanks in advance.


Solution

  • I managed to solve it like this:

    import { auth } from '../lib/auth';
    import { getSession } from "next-auth/react";
    
    private async setRequestToken() {
        let userSession;
    
        if (typeof window == "undefined") {
            userSession = await auth();
        } else { 
            userSession = await getSession();
        }
            
        const user = userSession?.user as SessionUserType;
        const token = user?.access_token;
    
        return token;
    }
    

    The typeof window will be undefined when the request is made from a server component so with this condition the request will use the server or client method of Auth.js to get the user session.