The Big TypeScript Rewrite
This is a BREAKING CHANGE (Major) release.
I did a full rewrite of the library in TypeScript, both as an exercise for me and to provide better types by default for consumers of the library. Since it was a full rewrite I took the opportunity to solve most of the issues from the GitHub repository along with feature requests.
Hope you like it. You'll find a migration guide in these changes.
Changes:
- The library was renamed to
iron-session
(since it works on all Node.js HTTP frameworks) - TypeScript: We have better types and you can now easily type check your session data (see usage in README). Fixes #369. Fixes #368.
- You can access and set session data directly on req.session.* instead of having to call .get()/.set()/.unset()
- get/set/unset methods were removed
- The library exposes different wrappers for Next.js API Routes, Next.js getServerSideProps, and Express.js middleware (see migration guide)
- List of passwords (rotation) must now be passed as objects like {1: 'password1', 2: 'password2'}
- When upgrading previous sessions will be kept which means that you can safely upgrade and your users will not lose their data or be logged out
- We now expose sealData/unsealData methods to create magic links and impersonation flows.
iron-store
is no more used. - We have updated the examples (Next.js, Next.js with TypeScript and Express.js) to use the new API
- The library is now published as an ES module along with CommonJS
- We now warn on bad usage (http + secure or save called after the response was sent). Fixes #8
- We now automatically set the cookie to secure or not secure based on the protocol.
- You can now have "session cookies" by passing {cookiesOptions: {maxAge: undefined}}. Fixes #340
- We handle the case where the cookie has been tampered with (we generate a new one). Fixes #380
Migration guide:
1. Uninstall next-iron-session
and install iron-session
:
npm remove next-iron-session
npm add iron-session
2. Change import paths in your code:
Before:
import { withIronSession } from "next-iron-session";
After:
import { withIronSessionApiRoute, withIronSessionSsr } from "iron-session/next";
import { ironSession } from "iron-session/express";
3. Change your code to use the new API:
Before:
req.session.set("user", { name: "John" });
const user = req.session.get("user");
req.session.unset("user");
After:
req.session.user = { name: "John" };
const user = req.session.user; // or use req.session.user directly
delete req.session.user;
4. (Optional) Remove secure flag from your options
The cookie secure flag is now automatically set based on http/https unless you want to change it.
Before:
withIronSession(handler, {
password: "complex_password_at_least_32_characters_long",
cookieName: "myapp_cookiename",
// if your localhost is served on http:// then disable the secure flag
cookieOptions: {
secure: process.env.NODE_ENV === "production",
},
});
After:
withIronSessionApiRoute(handler, {
password: "complex_password_at_least_32_characters_long",
cookieName: "myapp_cookiename",
});
5. (Optional) Change the format of your password
If you were passing down a list of passwords (for password rotations) then you need to update it to:
Before:
withIronSession(handler, {
password: [
{
id: 2,
password: "complex_password_at_least_32_characters_long",
},
{
id: 1,
password: "complex_password_at_least_32_characters_long",
},
],
});
After:
withIronSessionApiRoute(handler, {
password: {
2: "another_password_at_least_32_characters_long",
1: "complex_password_at_least_32_characters_long",
},
});
6. (Optional) Replace iron-store usage with sealData/unsealData
If you were using iron-store
to create seals for magic links or impersonation flows then you can replace it with sealData/unsealData.
Because we no more needed get/set/unset methods. We completely ditched the iron-store library that was initially built for next-iron-session needs.
Before:
const store = await ironStore({
password: "complex_password_at_least_32_characters_long",
ttl: 14 * 24 * 60 * 60 * 1000
});
store.set("user", { name: "John" });
const seal = await store.seal();
// later on, in a different file:
const store = await ironStore({
seal: req.query.seal,
password: "complex_password_at_least_32_characters_long",
ttl: 14 * 24 * 60 * 60 * 1000
});
const user = store.get("user);
After:
import { sealData } from "iron-session";
const store = {
user: { name: "John" },
};
const seal = await sealData(store, {
password: "complex_password_at_least_32_characters_long",
// ttl is always 14 days by default
});
// later on, in a different file:
import { unsealData } from "iron-session";
const store = await unseatData(req.query.seal, {
password: "complex_password_at_least_32_characters_long",
});
const user = store.user;
5. (Optional) Check the best way to use TypeScript with the library
Have a look at the README to know how to do that, here: https://github.com/vvo/iron-session#session-wrappers
Enjoy!