Having trouble retrieving the user-object within tRPC createContext using express

I'm encountering an issue with my tRPC configuration where it is unable to access the express session on the request object.

Currently, I am implementing passport.js with Google and Facebook providers. Whenever I make a request to a regular HTTP route (outside of the tRPC router), I am able to retrieve the user info by calling req.user.

Here is a snippet from my app.ts file:

import * as trpc from '@trpc/server';
import * as trpcExpress from '@trpc/server/adapters/express';

const appRouter = trpc
    .router()
    .mutation('addTodo', {
        input: z.string(),
        resolve: ({input, ctx}) => {
            // Add a todo
        },
    });

const app = express();
app.use(
    session({
        secret: 'use an env-variable here',
    }),
);
app.use(passport.initialize());
app.use(passport.session());

app.use(
    '/trpc',
    trpcExpress.createExpressMiddleware({
        router: appRouter,
        createContext: (ctx: trpcExpress.CreateExpressContextOptions) => {
            // === ISSUE OCCURS HERE ===
            console.log(ctx.req.user);
            //                   ^ RETURNS UNDEFINED
            return ctx;
        },
    }),
);

app.get("ping", (req, res) => {
    console.log(req.user);
    //                ^ RETURNS THE USER
    res.send("pong");
})

While it may seem like tRPC does not provide user information, there might be a workaround available. Any suggestions on how to address this challenge?

Answer №1

My familiarity lies more within the realm of express sessions rather than passport, so understanding how passport works is a bit uncertain for me. However, I believe the underlying concept might remain similar.

function createContext(opts: trpcExpress.CreateExpressContextOptions) {
  let user = {};
  if (opts.req.session.user) {
    user = opts.req.session.user;
  }

  return {
    user
  };
}

type Context = inferAsyncReturnType<typeof createContext>;
const t = initTRPC.context<Context>().create();
const appRouter = t.router({
  hello: t.procedure.query(({ ctx, input }) => {
    console.log("user", ctx.req?.session?.user);
    console.log({ input });
    return "Hello world";
  }),

  session: t.procedure.query(({ ctx, input }) => {
    console.log({ input });
    ctx.req.session.user = { name: "jane" };
    return "session created";
  }),
});

app.use(
  "/trpc",
  trpcExpress.createExpressMiddleware({ router: appRouter, createContext })
);

In conclusion, ensure to examine the req.session object for the user and subsequently include it in the context's returned object.

Answer №2

I encountered a similar issue, although mine was related to typescript. Upon further investigation, I realized that the request types were not aligned and needed to be adjusted in order for my session to be accessible.

For those utilizing typescript, consider typing your context as shown below:

import { CreateExpressContextOptions } from '@trpc/server/adapters/express'
import { Request } from 'express'
import session from 'express-session'

// Define a custom session type by extending the session type from 'express-session' and including additional properties like userId
export type Session = session.Session &
  Partial<session.SessionData> & { userId?: string }

// Update the ExpressRequest type to incorporate the custom session into the express request object
type ExpressRequest = Omit<CreateExpressContextOptions, 'req'> & {
  req: Request & { session: Session }
}

export const createContext = ({
  req,
  res,
}: ExpressRequest) => {
  return {
    req,
    res,
  }
}

export type Context = inferAsyncReturnType<typeof createContext>

Answer №3

I implemented this in my custom client-side fetcher for trpc integration

{
  credentials: "include"
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the process of dynamically incorporating headers into requests within react-admin

Currently utilizing react-admin with a data provider of simpleRestProvider. I am in need of a solution to dynamically add headers to requests based on user interactions. Is there a way to achieve this? Appreciate any assistance. Thank you! ...

"EPERM: unable to rename file due to permission restrictions" error occurs when using Express session with session-file-store library

Currently, I am developing a node application that operates on the express web server using express-session and session-file-store for managing sessions. Since incorporating these components into my project, my debug console has been inundated with errors ...

My Node.js application is encountering an issue when attempting to establish a connection with SQL Server - nothing appears on the console, even in the absence of any errors

The following code snippet is from the index.js file. Upon visiting the link "localhost:300/admins/", the code is supposed to establish a connection with SQL Server and retrieve the result on the console. I confirm that my Microsoft SQL Server Management ...

Seeking a solution for inserting input values into a JSON file within a node.js environment

As I was developing my new project, a to-do list web application, Below is the code snippet from 'todo.html' : <html> <head> <title>My TODO List</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery ...

The onSubmit function in React JavaScript is failing to execute, it is not triggering and no error message is being displayed on the frontend console

As a newcomer to React.js, I recently came across an article detailing how to perform CRUD operations with React Express and MongoDB. However, after implementing the code, I encountered an issue when trying to add a user. Upon clicking the 'Save' ...

What is the process for updating the Vue template during runtime?

Currently, I am working on a CMS-based Vue page. Within this page, there is a root container that contains two child containers structured as follows: <div id="app"> <div class="above-the-fold">...</div> <di ...

What is the method for adding pages to the ion-nav component in Ionic with Angular?

How can I implement a UINavigationController-like functionality in iOS using an ion-nav element? The example provided here is in Javascript, but I need assistance with implementing it in Angular. Specifically, I'm unsure of how to programmatically add ...

Express Stormpath: Preserve custom data

Running an express server with express-stormpath for authentication and storing custom user data has been smooth sailing. But I'm facing a challenge when it comes to posting data to the server and saving it to stormpath. Here's how my current po ...

What is the best way to generate a switch statement based on an enum type that will automatically include a case for each enum member?

While Visual Studio Professional has this feature, I am unsure how to achieve it in VS Code. Take for instance the following Colors enum: enum Colors { Red, Blue, When writing a switch statement like this: function getColor(colors: Colors) { swi ...

Direct all paths to the base path "/" using Express

Is there a way to redirect all URLs containing "/something" in Express to the base path "/:=", while still maintaining additional paths to their respective pages? For instance, I would like to implement the following redirects: "/something" redirects to ...

Transmit: Forwarding information back to the recipient

My goal is to send an Http Post request (Registration form) using Angular, have it processed in the API, and if any errors occur like Please enter a username..., I want to return an error message to the client. Below is the Angular code for reference. Than ...

What is the significance of the colon before the params list in Typescript?

Consider the following code snippet: import React, { FC } from "react"; type GreetingProps = { name: string; } const Greeting:FC<GreetingProps> = ({ name }) => { // name is string! return <h1>Hello {name}</h1> }; Wha ...

Utilizing ExpressJS in a NodeJS application with ES6 and Typescript

After confirming my information, I discovered that in an ES6 application, it is necessary to import dependencies using import .. from '..' instead of var .. = require('..'). I made the necessary changes to the imports, but encountered ...

When utilizing CKEditor in conjunction with ExpressJS, HTML tags may be displayed in the browser

Check out my app.js code below: <!DOCTYPE html> <html lang="en> <head> <meta charset="UTF-8> <meta name="viewport" content="width=device-width, initial-scale=1.0> <meta http-equiv="X-UA-Compatible" content="ie= ...

Using Typescript, Angular, and Rxjs to retrieve multiple HttpClients

I am looking to send get requests to multiple endpoints simultaneously, but I want to collect all the responses at once. Currently, this is how a single endpoint request is handled: public getTasks(): Observable<any> { this.logger.info('Ta ...

Creating a Circle with Pixi.js v4 and Typerscript in IONIC 2

I have been attempting to create a custom class in TypeScript that utilizes PIXI.js to draw circles. Below is the code for my home.ts class: import { Component, ViewChild, ElementRef } from '@angular/core'; import { NavController } from 'i ...

What is the best way to obtain / and /:specificText in node.js?

app.get('/',function(req,res,next){ app.use(express.static(html file); next(); }); app.get('/:someText',function(req,res){ var x = req.params.someText; res.send(x); }); Even though I am able to get the output for bot ...

Error message: NGINX combined with Express.js and socket.io, page not found

I currently have a node/express.js/socket.io application set up on an Ubuntu Server running on port 3002. I've made sure to open all ports on the machine for accessibility. When accessing the app directly at 11.111.111.1:3002/, everything runs smooth ...

Apply a CSS class when the tab key is pressed by the user

Currently in my Angular 14 project, I am working on a feature where I need to apply "display: block" to an element once the user reaches it using the tab key. However, I am struggling with removing the "display: block" when the user tabs out of the element ...

Having trouble updating a specific document in my MongoDB collection

I am facing an issue with my function that reads data from the database. I am trying to change the value of the "hasVoted" field in my Voters model from false to true, but it is not reflecting in the database. Even after setting data.hasVoted = true and c ...