Is there a way for me to access the request.user object within a middleware when the user is obtained from the JwtAuthGuard?

I'm in the process of developing a middleware to retrieve a member entity and attach it to the request object. However, I require the userId from the user object obtained through JwtAuthGuard, and unfortunately the guards are executed after middlewares.

One solution I am considering is creating an interceptor instead of a middleware to handle this task or incorporating the authentication directly into the middleware logic.

Below is the middleware code I have been working on:

@Injectable()
export class SpaceMemberMiddleware implements NestMiddleware {
  constructor(private readonly membersService: MembersService) {}

  async use(req: any, res: any, next: () => void) {
    const user: User = req.user;

    const member: Member = await this.membersService.findByUserId(user.userId);
    if (!member) throw new BadRequestException();

    req.member = member;

    next();
  }
}

This is followed by my AuthGuard:

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);

    return isPublic || super.canActivate(context);
  }
}

Lastly, here is my Strategy implementation:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly usersService: UsersService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
    });
  }

  async validate(payload: { username: string }): Promise<User> {
    const user: User = await this.usersService.findOneByCognitoId(
      payload.username,
    );

    if (!user) throw new UnauthorizedException();

    return user;
  }
}

I would greatly appreciate any recommendations or suggestions on how to proceed with this setup. Thank you for your understanding, and please excuse any language errors as English is not my first language. Thank you.

Answer №1

Given that the Interceptors are activated following the Middlewares (as detailed in the NestJS documentation), it may be beneficial to implement an Interceptor for your scenario.

You could create something similar to this:

@Injectable()
export class SpaceMemberInterceptor implements NestInterceptor {
  public intercept(context: ExecutionContext, handler: CallHandler): Observable<unknown> {
    const request = context.switchToHttp().getRequest();
    const user: User = request.user; // ensuring the user is authorized

    const member: Member = await this.membersService.findByUserId(user.userId);
    if (!member) throw new BadRequestException();
    
    request.member = member
    
    return handler.handle();
  }
}

Then simply configure the interceptor like so:

@UseInterceptors(new SpaceMemberInterceptor())
export class CatsController {}

Furthermore, you have the option to set up the interceptor at a global or route level based on your requirements (refer to the documentation)

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

A guide on utilizing the TypeScript compilerOptions --outDir feature

Recently, I encountered an error message from the compiler stating: Cannot write file 'path/file.json' because it would overwrite input file. After some investigation, most of the solutions suggested using outDir to resolve this issue. Although t ...

Setting up Datatable in Angular 2+ without relying on jQuery

I need assistance with initializing a datatable for a table that has a unique id. Can you provide guidance on the syntax to achieve this? Here is an example of my table structure: <table id="myDataTable"> <thead> <tr> ...

Searching for similar but not identical results using Knex.js

I am seeking a solution to retrieve similar posts without including the post itself. Here is my approach: export async function getSimilars(slug: string) { const excludeThis = await getBySlug(slug) const posts = await knex('posts') .whe ...

Issue with TypeScript Declaration File in NPM module functionality

Recently, I've been working on developing a package for NPM. It's essentially a JSON wrapped database concept, and it has been quite an enjoyable project so far. However, I've been facing some challenges when trying to include declarations f ...

Retrieving error messages and status codes using Laravel and JWT authentication

One of the challenges I'm facing is implementing JWT Auth in my Laravel + Vue SPA. When checking the credentials in my Controller, the code looks like this: try { if (!$token = JWTAuth::attempt($credentials)) { return response()- ...

Determine the accurate data types while transforming an array into an object using a specific key

I have an array of elements, each with a unique category string property. I aim to transform this into a structure where the category serves as the key and the original element is the value. To tackle this, I first verify that I possess a correctly typed ...

The communication between Angular and Unity using SignalR for messaging is not functioning properly, as I am unable to

Trying to establish a connection between Angular and Unity has been challenging for me. I can't seem to get them to communicate with each other. My goal is to have Angular "announce" when someone enters a room, and have Unity "greet" the user enterin ...

Mixing a static class factory method with an instance method: a guide

After introducing an instance method addField in the code snippet below, I encountered an issue with the Typescript compiler flagging errors related to the static factory methods withError and withSuccess: The error message states: 'Property ' ...

Troubleshooting mistakes in Typescript import syntax and beyond

During the development of this project in react and typescript using create-react-app, I encountered no issues. Now, my aim is to publish one of the components on npm. I have come to understand that I need to build this component separately from an existi ...

Creating a String-only pattern Validator: A step-by-step guide

Below is the code I've written: ***<input type="text" placeholder="First Name" name="firstName1" [(ngModel)]="firstName" #firstName1="ngModel" required pattern="^[a-z0-9_-]{8,15}$" >*** ...

Create a new map in Typescript by initializing it with an array: `new Map([[key1, value1], [key2, value2]])

Do these two initializations differ in functionality? The following code snippet works as expected: private screensMap: Map<string, ComponentType<any>>; public constructor() { this.screensMap = new Map() .set(BootstrapLaunch.name ...

The status of the Office.js appointment remains updated even after the saveAsync callback is executed

Utilizing the Office JavaScript API for an Outlook add-in, I encountered a issue with some code designed to save an appointment and close its window. Despite saving the appointment through the API, I continue to receive a "Discard changes" confirmation dia ...

React array fails to update upon modification

Hey there! I've created a component that takes an array of strings, combines them, and then renders a typing animation by wrapping each character in a span tag with toggling opacity from 0 to 1. I noticed an issue when switching the order of displaye ...

Session storage causes NodeJs, Apollo, and typescript server to stall and become unresponsive

As a newcomer to NodeJs, I've been following Ben Awad's full-stack tutorial on YouTube. You can check it out here. Everything was working fine after setting up my server. I added express-session for session storage and connected it to Redis usin ...

Tips for customizing Material UI CSS default properties in React

I'm currently working on a React project and utilizing the 'Table' component from Material UI. The default CSS properties of this table, along with its components like TableHead, TableCell, and TableRow, are proving difficult to override whi ...

Show the Array List in a left-to-right format

Is there a way to display an array list from left to right with a div scroll, instead of top to bottom? I am having trouble achieving this. Here is my demo code for reference. HTML <div> <h2 class="ylet-primary-500 alignleft">Sessions</h ...

What is the best way to transform a Map<string, boolean> into an array of objects with key-value pairs {key: string, value: boolean

I'm currently working on a React project that incorporates TypeScript, and I've successfully implemented dynamic permission creation on the user creation page by utilizing this particular code snippet. The permissions being used on the page are m ...

Tips for showcasing an array containing two different types of objects in Angular

After sending a request to a remote server, I am returned with a JSON array. However, the array can contain two different types of JSON objects: [ { "country": "USA", "caseCount": 561, "caseDates": [], ...

Is there a way to programmatically verify my credentials in the Microsoft Graph API using Python, using my unique username and password

I am currently working with an Excel (.xlsx) file stored in my Office 365 (Sharepoint Online) account and I am looking to use Python for programmatically accessing the data within the worksheets. It seems that the Microsoft Graph API is the appropriate too ...

What kind of function am I using and passing as props in React when working with TypeScript?

I recently developed a customized Checkbox component. The TypeScript setup in my project doesn't allow the use of any type, so I'm struggling to define the specific type for the handleCheckbox() function (found within the FilterBox component) th ...