Next.js Discord

Discord Forum

Question about next-auth and custom backend

Unanswered
Prairie yellowjacket posted this in #help-forum
Open in Discord
Prairie yellowjacketOP
Hey guys I'm having problem with getting my NextJs14 app with next auth to work with my custom backend in NestJs. I'm looking for a solution or I would like to know is it possible to connect next oauth with my backend. I tried some alternative ways but doesn't seem to be working

28 Replies

Yes, use api for it
nestjs as a api
and communicate using fetch requests
Prairie yellowjacketOP
problem is my signIn callback is working fine returning jwt and refresh token from backend, but I cannot connect it to jwt callback, jwt callback is taking googleProvider jwt token... credentials provider works fine, and I'm using refresh token strategy on my backend
Prairie yellowjacketOP
from async jwt function in callback, token.backendTokens.expiresIn this variable, it is saying that is undefined...
my sign in function returns { user, backendTokens } which is holding user and tokens from backend, but it doesn't seem to be passed in jwt()
Prairie yellowjacketOP
yes everything works fine
await callback(user, account, profile);
this function is returning everything from backend normally how it should be
it returns this object example:
 {
  user: {
    id: 'clqzxn1lw0000n3hm2arqby0g',
    firstName: 'hello',
    lastName: 'hello',
    password: '',
    email: 'hello@gmail.com',
    emailVerified: null,
    phone: null,
    image: 'hehe'
  },
  backendTokens: {
    accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MDQ0NDkzNTgsImV4cCI6MTcwNDQ0OTM3OH0.AK4vrzEuND9OsruMiOWME6qNCkFjmYvaa-IwPNHelJ0',
    refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MDQ0NDkzNTgsImV4cCI6MTcwNTA1NDE1OH0.u82pfwGacZBCTYYV657S8DkoAb80LC-zwxeAjZv7ZGI',
    expiresIn: 1704449378239
  }
}
@Prairie yellowjacket Click to see attachment
if (!token.backendTokens?.expiresIn || new Date().getTime() < token.backendTokens?.expiresIn) return token;

maybe try this, since the backendTokens only available after the refreshToken function?
Prairie yellowjacketOP
is there any good next auth tutorials that include oauth and custom backend?
@Prairie yellowjacket Click to see attachment
what does the endpoint of /auth/login return?
Prairie yellowjacketOP
I tried to modify callback removed sign in function, only left jwt function, on first login when I click on login with google, token gets stored in cookies and it persists user as logged, but backendUser from backend call gets deleted in the process and user and account fields get undefined
async jwt({ token, user, account, profile }: any) {
            console.log('user', user);
            console.log('account', account);
            if (account?.provider === 'credentials') {
                console.log('user from credentials:', user);
                if (user) return { ...token, ...user };
                if (new Date().getTime() < token.backendTokens.expiresIn) return token;
            } else {
                const backendUser = await callback(user, account, profile);
                console.log('user from oauth:', backendUser);
                if (backendUser)
                    return { token: { ...backendUser.backendTokens }, user: { ...backendUser.user } };

                if (new Date().getTime() < backendUser.backendTokens.expiresIn) return token;
            }

            return await refreshToken(token);
        },
I don't know is it just me but it's really hard to make a good authentication and I always had problems, can't find a really good solution anywhere
@Ray https://www.youtube.com/watch?v=cDWytA0V2kI this maybe
Prairie yellowjacketOP
that's a really good solution but not for oauth
@Ray what does the endpoint of `/auth/login` return?
if you can return the refreshToken from this endpoint /auth/login, then the refreshToken will be avaliable in the token object on jwt callback
async authorize(credentials, req) {
    if (!credentials?.email || !credentials?.password) return null;
    const { email, password } = credentials;
    const res = await fetch(process.env.NEXT_PUBLIC_BACKEND_API + '/auth/login', {
        method: 'POST',
        body: JSON.stringify({
            email: email,
            password
        }),
        headers: {
            'Content-Type': 'application/json'
        }
    });
    if (res.status == 401) {
        console.log(res.statusText);

        return null;
    }
    const user = await res.json();
    const tokens = await fetchToken(user);
    return {...user, ...tokens};
}

like this
Prairie yellowjacketOP
credentials provider work fine with this code, it persist user and data is fetched normally, problem is GoogleAuth
async jwt({ token, user, account }: any) {
        if (account['provider'] === 'google') return token;
    if (user) return { ...token, ...user };

    if (new Date().getTime() < token.backendTokens.expiresIn) return token;

    return await refreshToken(token);
},

how about this?
Prairie yellowjacketOP
it would work but it's not connected with my backend, when user logs in with google I want to save user on my backend, and persist user from my backend if you get me
Prairie yellowjacketOP
thanks brother, I'll take a look