yxaepnm
yxaepnm12mo ago

Set server response headers from TRPC standalone adapter

Hi I am trying to implement my own authentication in Trpc. For this I need to create a session on the backend and return appropriate headers like set cookie for session-token and csrf-token. How can I set these headers from within a mutation when using the standalone adapter.
Could find anything here or in the docs. Thank you 🙏
3 Replies
Alex / KATT 🐱
Alex / KATT 🐱12mo ago
Pass through the req/res objs from createContext and set it in the mutation like you'd do without trpc
yxaepnm
yxaepnm12mo ago
Thanks for the idea, managed to do it as follows: server initialization:
const { databaseUrl } = parseEnvironmentVariables();
const appContext = await createAppContext({ databaseUrl });

const server = createServer((req, res) => {
const requestContext = createRequestContext({
appContext,
request: req,
response: res,
});
const handler = createHTTPHandler({
router: initRouter(),
createContext: () => requestContext,
});
handler(req, res);
});

server.listen(options.port);
const { databaseUrl } = parseEnvironmentVariables();
const appContext = await createAppContext({ databaseUrl });

const server = createServer((req, res) => {
const requestContext = createRequestContext({
appContext,
request: req,
response: res,
});
const handler = createHTTPHandler({
router: initRouter(),
createContext: () => requestContext,
});
handler(req, res);
});

server.listen(options.port);
mutation definition:
export const initRouter = () =>
router({
create: publicProcedure.mutation(async (opts) => {
const { appContext, requestContext } = opts.ctx;

const sessionToken = nanoid(21);
const sessionCookie = new Cookie({
key: sessionTokenCookieName,
value: sessionToken,
sameSite: "strict",
httpOnly: true,
});

const csrfToken = nanoid(21);
const csrfCookie = new Cookie({
key: csrfTokenCookieName,
value: csrfToken,
sameSite: "strict",
httpOnly: true,
});

requestContext.response.setHeader("Set-Cookie", [
sessionCookie.toString(),
csrfCookie.toString(),
]);

await appContext.db.insert(session).values({
sessionToken,
});

return csrfToken;
}),
});
export const initRouter = () =>
router({
create: publicProcedure.mutation(async (opts) => {
const { appContext, requestContext } = opts.ctx;

const sessionToken = nanoid(21);
const sessionCookie = new Cookie({
key: sessionTokenCookieName,
value: sessionToken,
sameSite: "strict",
httpOnly: true,
});

const csrfToken = nanoid(21);
const csrfCookie = new Cookie({
key: csrfTokenCookieName,
value: csrfToken,
sameSite: "strict",
httpOnly: true,
});

requestContext.response.setHeader("Set-Cookie", [
sessionCookie.toString(),
csrfCookie.toString(),
]);

await appContext.db.insert(session).values({
sessionToken,
});

return csrfToken;
}),
});
Not the full code due to character limit, but should suffice if you are looking to do the same :)!
mattddean
mattddean11mo ago
This is great, thank you. What's the new Cookie() library you're using? It looks nice