2

I'm using nuxt 3 with @sidebase/nuxt-auth for my PKCE OAUTH2 authentication flow with my Laravel API which uses Laravel passport. I am done with the implementation of the authentication flow from the Laravel side, and done with the nuxt side, getting the token and saving it.
Then I have created a custom interceptor with ofetch, in order to send the access_token that I fetch from the session at every request.
but when the access token is expired, it is not getting refreshed automatically.
am i missing some configuration? or refresh token is a custom logic i have to write?

I've tried the JWT callback in the @sidebase/nuxt-auth but it didn't work.

This is my current auth configuration:

import {NuxtAuthHandler} from '#auth'
import useCustomFetch from "~/composables/useCustomFetch";

export default NuxtAuthHandler({
    providers: [
        {
            id: 'passport',
            name: 'Passport',
            type: 'oauth',
            version: '2.0',
            authorization: {
                url: "https://example.com/oauth/authorize",
                params: {
                    scope: '',
                    prompt: 'front',
                },
            },
            clientSecret: 'awd',
            clientId: "96695f40-1578-4b7c-974b-181e0344dcac",
            token: 'https://example.com/api/v1/oauth/token',
            userinfo: 'https://example.com/api/v1/user',
            checks: ['pkce'],
            profile(profile: { success: { user: any } }) {
                const data = profile.success.user
                return {
                    id: data.id,
                    name: data.first_name + " " + data.last_name,
                    email: data.email,
                };
            },
        }
    ],
    cookies: {

    },
    callbacks: {
        async jwt({token, account, user}) {
            if (account && user) {
                return {
                    access_token: account.access_token,
                    refresh_token: account.refresh_token,
                    accessTokenExpires: account.expires_at,
                    user
                }
            }
            // @ts-ignore
            if (Date.now() < token.accessTokenExpires * 1000) {
                return token
            }

            return await refreshAccessToken(token);
        },
        async session({session, token}) {
            // @ts-ignore
            session.user = token.user
            // @ts-ignore
            session.access_token = token.access_token
            // @ts-ignore
            session.error = token.error
            return session
        },
    },
    events: {
        async signOut() {
            try {
                await useCustomFetch('/oauth/tokens/revoke', {
                    method: 'POST'
                })
            } catch (e) {
                console.log(e);
            }
        },
    }
})

async function refreshAccessToken(token: any) {
    try {
        const url = "https://example.com/api/v1/oauth/token";

        // @ts-ignore
        const refreshedToken: AuthResponse = await $fetch(url, {
            headers: {
                "Content-Type": "application/json",
            },
            method: "POST",
            body: {
                grant_type: 'refresh_token',
                refresh_token: token.refresh_token,
                client_id: "96695f40-1578-4b7c-974b-181e0344dcac"
            }
        });
        token.access_token = refreshedToken.access_token;
        token.accessTokenExpires = Date.now() + refreshedToken.expires_at * 1000;
        token.refresh_token = refreshedToken.refresh_token;
        return {
            ...token
        }
    } catch (error) {
        console.log(error)

        return {
            ...token,
            error: "RefreshAccessTokenError",
        }
    }
}

interface AuthResponse {
    access_token: string,
    refresh_token: string,
    token_type: string,
    expires_at: number,
}

0 Answers0