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,
}