-
-
Notifications
You must be signed in to change notification settings - Fork 252
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
Support for next js 13 server side components #560
Comments
This is blocking my Next.js 13 upgrade path, would love to see a resolution for this, cheers! |
The issue is very urgent and critical for my project! |
I still use iron-session with Next 13 to handle auth/session. My solutions is like this: // lib/getRequestCookie.ts
import { SessionUser } from "@/api/user";
import { unsealData } from "iron-session";
import { ReadonlyRequestCookies } from "next/dist/server/app-render";
/**
* Can be called in page/layout server component.
* @param cookies ReadonlyRequestCookies
* @returns SessionUser or null
*/
export async function getRequestCookie(
cookies: ReadonlyRequestCookies
): Promise<SessionUser | null> {
const cookieName = process.env.SESSION_COOKIE_NAME as string;
const found = cookies.get(cookieName);
if (!found) return null;
const { user } = await unsealData(found.value, {
password: process.env.SESSION_COOKIE_PASSWORD as string,
});
return user as unknown as SessionUser;
} And then, in protected layout or page (preferably layout), I do: import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { getRequestCookie } from "@/lib/getRequestCookie";
export default async function TenantLayout({
children,
}: {
children: React.ReactNode;
}) {
console.log("Entering TenantLayout boundary");
const user = await getRequestCookie(cookies());
// Prevent non logged user to acces all pages in the tenant layout tree
if (!user) {
redirect("/login");
}
return (
<>
// header component
{children}
// footer component
</>
);
} So far it works perfectly well. |
Thank you @poltang! I was able to use |
Thanks for sharing this @poltang. Would be great to see this added to |
I agree with you @ajsharp that it
But for me it's a matter of preference. Writing-wise I prefer this new approach since we don't need to write separate ssr logic like this example: export default function SsrProfile({
user,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<Layout>
{/* Page content goes here */}
</Layout>
)
}
export const getServerSideProps = withIronSessionSsr(async function ({ req, res }) {
const user = req.session.user;
if (user === undefined) {
res.setHeader("location", "/login");
res.statusCode = 302;
res.end();
return {
props: {
user: { isLoggedIn: false, login: "", avatarUrl: "" } as User,
},
};
}
return {
props: { user: req.session.user },
};
},
sessionOptions); With new approach this logic goes into page body with simpler code and no need to create export default async function Page() {
const user = await getRequestCookie(cookies());
if (!user) {
redirect("/login");
}
return (
<>
{/* Page content goes here */}
</>
);
} And again, as we now have layout, we can colocate this to it and then IF we have hundreds of pages we will be grateful not to call |
Thanks for this solution @poltang, it was very useful. One thing that was still missing to me was a way to query the api passing the auth cookie. I was not really able to use the withSessionSsr, so I came up with this: import { cookies } from 'next/headers'
async function getUser() {
const sessionCookie = cookies().get(
process.env.SESSION_COOKIE_NAME as string
)
if (sessionCookie) {
const Cookie = `${sessionCookie.name}=${sessionCookie.value}`
const res = await fetch(`${apiDomainAndProtocol}/api/user`, {
headers: {
Cookie,
},
})
... Please, do you have another suggestion? |
@brunoreis I'm afraid I don't understand with what you mean by query the api passing the auth cookie. All my protected APIs now share the same shape like this: async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = req.session.user;
if (!user) {
return res.status(401).json( ERROR_401 );
}
// do some stuff
const result = ...
return res.json(result);
}
export default withIronSessionApiRoute(handler, sessionOptions) |
Add next.js-13-typescript example pls |
@poltang, I think I'm still a little bit confused in this SSR world logic. I do have an /user route that I use in frontend to access the user data and I'm hitting that api route from the ssr in order to grab the same data when rendering in the server. In fact I don't need to grab my data through an api call, right? I'm already in the server. Although it feels like a good thing to access data from the server and from the frontend in the exact same way. |
I also wish I could create my login, logout and signup routes in the |
Is Poltang's example still the standard implementation method for using iron-session cookies with the current Next 13 app router? Or has there been anything new to newly use since the app router stable release in May? |
how to set the cookie? poltang |
How do we initially set cookies to the header securely with Iron Session? The code examples above are for when the cookie has been already set |
i want something like iron-session that can be use in nextjs 13, i love the way iron-session ecrypt the cookie and easily get the cookie with the actual value, is there any reference? |
I'm using this as of recently, which is working quite well Edit: It's for Route Handlers, it might be adapted for Server Components? export type DynamicSegments = {
params: { slug: string } | undefined;
};
export type RouteHandler = (
request: Request,
routeSegment: DynamicSegments
) => Promise<Response>;
export type RouteHandlerWithSession = (
request: Request & { session: IronSession },
routeSegment: DynamicSegments
) => Promise<Response>;
const ironSessionWrapper = (handler: RouteHandlerWithSession): RouteHandler => {
return async (request, routeSegment) => {
const cookieResponse = new Response();
const session = await getIronSession(
request,
cookieResponse,
sessionOptions
);
const sessionRequest = Object.assign(request, { session });
const response = await handler(sessionRequest, routeSegment);
const setCookie = cookieResponse.headers.get("set-cookie");
if (setCookie) {
response.headers.set("set-cookie", setCookie);
}
return response;
};
}; And using it like this: const POST: RouteHandlerWithSession = ironSessionWrapper(async (request) => {
request.session.destroy();
return NextResponse.json({});
}); |
it work perfectly thanks erwanvivien, but i still waitting till the iron-session maintainer release the official trick or docs |
Hey everyone 👋 I have Iron Session now fully working with support for NextJS App Router and Server Actions. It works without the need for wrappers and handlers. The feature update is provided with documentation and a working example application. Please refer to my comment under the Roadmap v8 issue thread for it, being available as a pull request. I would love your support in getting this PR approved so that we can complete the V8 branch to be pushed into the main branch to have Iron Session with NextJS 13 Server Side Components available for everyone to use. |
The old
getServerSideProps
api is deprecated, and you no longer have access to the request and response objects. Instead you get access to headers and cookies.It would be nice to have a new helper function like
withIronSessionSsr
for accessing the session in server side components.The text was updated successfully, but these errors were encountered: