ippo
ippo2y ago

express-session for tRPC

I am using express-session for all my servers to create session authentication. Is there something for tRPC that you can recommend, to get session authentication?
7 Replies
ippo
ippoOP2y ago
does anyone know a repo, that uses cookie authentication where the session-id is stored in a database/redis/memory and where on every request the user is queried and store in the req object?
tomheaton
tomheaton2y ago
you can send the auth cookie or similar with the request in the headers (https://trpc.io/docs/client/setup)
httpBatchLink({
url: 'http://localhost:3000/trpc',
// You can pass any HTTP headers you wish here
async headers() {
return {
authorization: getAuthCookie(),
};
},
}),
httpBatchLink({
url: 'http://localhost:3000/trpc',
// You can pass any HTTP headers you wish here
async headers() {
return {
authorization: getAuthCookie(),
};
},
}),
then define a middleware that uses the auth to find a matching session (in your redis etc.) (https://trpc.io/docs/server/middlewares)
const hasSession = middleware(async (opts) => {
const { req } = opts;

// get session from redis etc.
const session = await getSessionFromRedis(req.headers);

if (!session) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}

return opts.next({
ctx: {
user: session.user,
},
});
});
const hasSession = middleware(async (opts) => {
const { req } = opts;

// get session from redis etc.
const session = await getSessionFromRedis(req.headers);

if (!session) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}

return opts.next({
ctx: {
user: session.user,
},
});
});
ippo
ippoOP2y ago
@tomheaton but where do you set the cookie properties? the max age, the signature secret, its behavior and so on?
Mugetsu
Mugetsu2y ago
You can use express session as normal with trpc No magic Here. You dont need anything specilal just for trpc. Trpc is based on the req/res from express so you have access to the req.session within trpc routes.
ippo
ippoOP2y ago
this is how I setup my session with express-session:
app.use(
session({
name: "COOKIE_ID",
store: new RedisStore({
client: redis,
disableTouch: true,
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 1 day
httpOnly: true,
sameSite: "lax", // reLAXed CSRF - Cross Site Request Forgery
secure: true, // cookie only works in https
domain: ".myapp.com", // cookie only works if request comes from this domain
},
saveUninitialized: false, // not every session will be stored, only modified once
secret: "very complicated string", // this string is used to sign the cookie and protect it from modifications.
resave: false, // will not save the session in store on every request, only if was modified
})
);
app.use(
session({
name: "COOKIE_ID",
store: new RedisStore({
client: redis,
disableTouch: true,
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 1 day
httpOnly: true,
sameSite: "lax", // reLAXed CSRF - Cross Site Request Forgery
secure: true, // cookie only works in https
domain: ".myapp.com", // cookie only works if request comes from this domain
},
saveUninitialized: false, // not every session will be stored, only modified once
secret: "very complicated string", // this string is used to sign the cookie and protect it from modifications.
resave: false, // will not save the session in store on every request, only if was modified
})
);
Is there an equivalent for next-auth?
Mugetsu
Mugetsu2y ago
You need an adapter with next-auth. I see u use redis with express. Then either use up-stash adapter for redis or you need to roll out your own adapter for redis. There is custom adapter for redis on next-auth issues or discussions as I was in need for one too. You have to look for it https://next-auth.js.org/adapters https://authjs.dev/reference/adapter/upstash-redis https://authjs.dev/guides/adapters/using-a-database-adapter https://authjs.dev/concepts/faq#databases https://authjs.dev/reference/adapters
tomheaton
tomheaton2y ago
vercel just announced vercel-kv 🙌