New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v6 and Next 13 pages middleware #663
Comments
Thank you! |
Hello @viachaslau-latushkin , What makes you think otherwise? |
@Thanaen in middleware I am trying to apply refresh token logic. |
You can use sealData() and unsealData() to encrypt/decrypt the cookie values. Assuming you're doing an oauth/refresh token kind of thing, here's something I used recently: import {
IRON_COOKIE_NAME,
SessionData,
ironOptions,
} from './auth';
export async function middleware() {
const session = await getIronSession<SessionData>(cookies(), ironOptions);
const next = NextResponse.next();
if (!session.token?.expires_at) {
// no/invalid token, send user to auth
return NextResponse.redirect(getGoogleAuthURL());
}
if (session.token.expires_at < Date.now()) {
// refresh token
try {
const token = await refreshToken(session.token);
const sealed = await sealData(
{
...session,
token: { ...token, expires_at: Date.now() + token.expires_in * 1000 },
},
ironOptions,
);
next.cookies.set(IRON_COOKIE_NAME, sealed);
// await session.save(); // won't work
} catch (e) {
// some error while refreshing token, send user to auth
console.error(e);
return NextResponse.redirect(getGoogleAuthURL());
}
}
return next;
} |
@arthurjdam |
As @arthurjdam solution, here's the updated version that worked for me. Hope it may save time for others. This solution fixes the error middleware.ts export default async function middleware(req: NextRequest) {
const { isLoggedIn, exp } = await getSession();
// Refresh Token Rotation
if (isLoggedIn && exp && exp < Date.now() / 1000) {
try {
const newSession = await refreshToken();
const sealed = await sealData(newSession, sessionOptions);
const res = NextResponse.redirect(req.url);
res.cookies.set({
name: '[your-cookie-name]',
value: sealed,
});
return res;
} catch (e) {
await logout();
}
}
return NextResponse.next();
} authActions.ts export async function getSession() {
return await getIronSession<User>(cookies(), sessionOptions);
}
export async function refreshToken() {
const session = await getSession();
const res = await fetch(
`${process.env.NEXT_PUBLIC_BACKEND_BASE_URL}/user/refresh`,
{
method: 'POST',
headers: { Authorization: 'Bearer ' + session.refreshToken },
}
);
const { accessToken, refreshToken } = await res.json();
const newUser = jwt.decode(accessToken) as JwtPayload;
session.userToken = accessToken;
session.refreshToken = refreshToken;
session.exp = newUser.exp;
return session;
} P.S. I'm assuming the interface of my export interface User {
id: string;
isLoggedIn: boolean;
name: string;
userToken: string;
refreshToken: string;
exp: number | undefined;
} I'm available for any further clarifications or inquiries... |
Hi!
Thank you for your work!
I faced with problem in v6: save() and destroy() not working before return in nextjs middleware.
And changes applying only on next tick or after reloading page or on new request to pages/api folder.
"iron-session": "^6.3.1",
"next": "13.2.4"
The text was updated successfully, but these errors were encountered: