2022-08-12
1738
#nestjs
Clara Ekekenta
127096
Aug 12, 2022 ⋅ 6 min read

How to implement JWT authentication in NestJS

Clara Ekekenta Software Engineer and perpetual learner with a passion for OS and expertise in Python, JavaScript, Go, Rust, and Web 3.0.

Recent posts:

How to fix React routing loopholes with the React Router Middleware

How to fix React routing loopholes with the React Router Middleware

Learn how React Router’s Middleware API fixes leaky redirects and redundant data fetching in protected routes.

Ikeh Akinyemi
Nov 13, 2025 ⋅ 3 min read
How I used Mastra to build a prize-winning RAG agent

How I used Mastra to build a prize-winning RAG agent

A developer’s retrospective on creating an AI video transcription agent with Mastra, an open-source TypeScript framework for building AI agents.

Chinwike Maduabuchi
Nov 13, 2025 ⋅ 12 min read

Ensuring frontend data integrity with TanStack DB transactions

Learn how TanStack DB transactions ensure data consistency on the frontend with atomic updates, rollbacks, and optimistic UI in a simple order manager app.

Emmanuel John
Nov 13, 2025 ⋅ 11 min read
the replay november 12

The Replay (11/12/25): Stop making these useEffect mistakes

Discover what’s new in The Replay, LogRocket’s newsletter for dev and engineering leaders, in the November 5th issue.

Matt MacCormack
Nov 12, 2025 ⋅ 33 sec read
View all posts

9 Replies to "How to implement JWT authentication in NestJS"

  1. Also I think you messed up the order of steps for the auth module since the local strategy needs the auth service which is mentioned further down on how to create it.

  2. missing :

    npm install –save @nestjs/passport passport passport-local
    npm install –save-dev @types/passport-local

    and local strategy

    import { Strategy } from ‘passport-local’;
    import { PassportStrategy } from ‘@nestjs/passport’;
    import { Injectable, UnauthorizedException } from ‘@nestjs/common’;
    import { AuthService } from ‘./auth.service’;

    @Injectable()
    export class LocalStrategy extends PassportStrategy(Strategy) {
    constructor(private authService: AuthService) {
    super();
    }

    async validate(username: string, password: string): Promise {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
    throw new UnauthorizedException();
    }
    return user;
    }
    }

  3. So, I’m rendering templates via Nest.js, and some of those templates include client-side JavaScript (via tags) that needs to do API requests from the browser. What is the proper way to send the access token to the frontend so that it can be used via the JavaScript running in the browser? Should I just set the access token in the pre-rendered HTML (e.g. as an attribute of the element, so that the client-side JavaScript can just query the DOM to get the token for API requests? Or is that unsafe/non-secure?

    1. Sending access tokens to the frontend, especially if they’re intended to be used by client-side JavaScript, is a sensitive area that requires a security-focused approach. Here are some common practices and considerations:

      HTTP-Only Cookies: One common method for sending tokens to the frontend securely is to use HTTP-only cookies. These cookies cannot be accessed through JavaScript, thereby reducing the risk of cross-site scripting (XSS) attacks. But this method isn’t directly useful if your client-side script needs to access the token.

      Avoid Inline JavaScript: When you’re rendering templates server-side, avoid placing sensitive data in inline JavaScript or in the DOM. This can expose the data to XSS attacks.

      Frontend Session: If your frontend app requires the token, you might consider a strategy where you fetch the token in a secured way after the initial page load. This might be done through a secure API endpoint that returns the token as a JSON payload, which your frontend app can then store in memory (not in local storage due to security concerns). This token can then be used for subsequent API requests.

      Short-Lived Tokens: If tokens must be exposed to frontend code, make sure they are short-lived. This reduces the potential damage in case of exposure.

      Avoid Local Storage for Sensitive Tokens: The Web Storage (local storage and session storage) is vulnerable to XSS attacks. If an attacker can run JavaScript on your page, they can retrieve the tokens stored there. Instead, if you must store a token on the frontend, consider keeping it in a JavaScript variable which will exist only for the life of the page.

      Content Security Policy (CSP): Implement a strong CSP for your web application. This reduces the risk of XSS attacks by controlling which scripts and resources can be loaded and executed.

      Always Use HTTPS: Always ensure your application runs over HTTPS. This encrypts the traffic between the client and the server, protecting the token from being intercepted.

      Refresh Tokens: If using short-lived access tokens, also use refresh tokens (stored securely server-side) to obtain a new access token once the old one expires. This way, even if an access token is exposed, its short lifespan combined with the inability to refresh it limits potential damage.

      In summary, if your client-side JavaScript absolutely requires the access token, ensure you’re following best practices to minimize risks, such as those mentioned above. Ideally, reduce direct exposure of tokens to frontend code as much as possible.

  4. So what’s the reason behind using passport-local middleware, when one can just verify password in login method and call “validate” afterwards or throw an error? This middleware is useless in this case

  5. I am getting this error
    plz advise.Thanks

    ERROR [ExceptionHandler] JwtStrategy requires a secret or key
    TypeError: JwtStrategy requires a secret or key

Leave a Reply

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now