Authorization with External API

Hi all, I'm working on a project that consists of a mobile application in React Native and a desktop application in NextJS. I was hoping to be able to share an API between these two applications, so I've built one in NestJS for this purpose. I am trying to implement auth flow into a NextJS project. Currently, I am facing an issue: When I log in - I'm able to generate an access and refresh token just fine, but once it expires, I have to refresh twice because the refresh call doesn't appear ready in time prior to the API being called from the page component, thus resulting in an unauthorized error.
middleware.ts

export const refreshSession = async () => {
const refresh_token = cookies().get('refresh_token')?.value;

if (!refresh_token) return;

const { headers } = await fetch('http://localhost:3000/api/auth/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
cookie: cookies().toString(),
},
body: null,
credentials: 'include',
});

const setCookie = headers.get('set-cookie');

if (!setCookie) return;

const res = NextResponse.next();
res.headers.append('set-cookie', setCookie);

return res;
};

export async function middleware() {
return await refreshSession();
}
middleware.ts

export const refreshSession = async () => {
const refresh_token = cookies().get('refresh_token')?.value;

if (!refresh_token) return;

const { headers } = await fetch('http://localhost:3000/api/auth/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
cookie: cookies().toString(),
},
body: null,
credentials: 'include',
});

const setCookie = headers.get('set-cookie');

if (!setCookie) return;

const res = NextResponse.next();
res.headers.append('set-cookie', setCookie);

return res;
};

export async function middleware() {
return await refreshSession();
}
Page.tsx

export async function getUser() {
const res = await fetch('http://localhost:3000/api/users/me', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
cookie: cookies().toString(),
},
body: null,
credentials: 'include',
});

if (res.status !== 200) return;

const session = await res.json();

return session;
}

export default async function Page() {
const session = await getUser();

return (
<section>
<LoginForm />

<pre>{JSON.stringify(session, null, 2)}</pre>
</section>
);
}
Page.tsx

export async function getUser() {
const res = await fetch('http://localhost:3000/api/users/me', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
cookie: cookies().toString(),
},
body: null,
credentials: 'include',
});

if (res.status !== 200) return;

const session = await res.json();

return session;
}

export default async function Page() {
const session = await getUser();

return (
<section>
<LoginForm />

<pre>{JSON.stringify(session, null, 2)}</pre>
</section>
);
}
2 Replies
Twan
TwanOP2mo ago
I’ve realized that this isn’t how it’s supposed to be done and I have to use something like tRPC as a “middleware” for my external api. Does anyone have an idea of what is best practice and an example?
Twan
TwanOP2mo ago
GitHub
Need refresh page to get the cookies set in Middleware · vercel nex...
Summary @ Using NextJS 13.3 with App Dir and API Routes. I am trying to build a auth system with my external backend nodeJS. Basically, front send credentials to backend, backend validate and retur...
Want results from more Discord servers?
Add your server