Search code examples
reactjsnext.jsreact-hooksnext-authnext.js13

How to access Token in next-auth?


I want to implement my credentials login logic. The problem is i can't access token in useSession hooks. I need token to send it to backend for REST API's endpoints. I searched a lot, read a lot and even asked ChatGPT but nothing worked for me. This is my implemention

pages/api/auth/[...nextauth].ts;

import NextAuth, { AuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { getProfile } from 'utility/api/audience';

export const authOptions: AuthOptions = {
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        token: { label: 'Token', type: 'text' },
      },
      async authorize(credentials) {
        if (!credentials?.token) return null;
        const token = credentials.token;

        const { profile } = await getProfile(token);

        if (profile)
          return {
            email: profile.data.email,
            name: profile.data.fullName,
            id: profile.id,
            token,
          };
        else return null;
      },
    }),
  ],
};
export default NextAuth(authOptions);

In callback object I printed a lot of console.log but none of the parameters included token. just the email and name and some timestamp.

I will appreciate some help here.


Solution

  • After a lot of search and trying everything, I finally found something that worked.

    For those who want to achieve the same result as me just simply pass this callback in [...nextauth].ts

    export const authOptions: AuthOptions = {
      providers: [
        CredentialsProvider({
          name: 'Credentials',
          credentials: {
            token: { label: 'Token', type: 'text' },
          },
          async authorize(credentials) {
             const token = credentials.token || '';
            if (!token) return null;
    
            const { profile } = await getProfile(token);
    
            if (profile)
              return {
                ...profile,
                token,
              };
            else return null;
          },
        }),
      ],
      callbacks: { //  =====> Add Below Callbacks <=====
        jwt: async ({ token, user }) => {
          return { ...token, ...user };
        },
        session: async ({ session, token }) => {
          session.user = token;
          return session;
        },
      },
      secret: process.env.NEXTAUTH_SECRET,
    };
    

    Now useSession hook will return every data you pass it.

    NOTE: If your using typescript you can create a ts file in types/next-auth.d.ts

    and overwrite the Session Type like this

    import NextAuth from 'next-auth/next';
    
    declare module 'next-auth' {
      interface Session {
        user: {
          name?: string;
          token?: string;
          email?: string;
        };
      }
    }