8-building-secure-graphql-apis-with-nestjs-and-jwt-authentication.html

Building Secure GraphQL APIs with NestJS and JWT Authentication

In today's tech-driven world, APIs form the backbone of modern applications, enabling seamless communication between front-end and back-end systems. One of the most popular frameworks for building server-side applications is NestJS, which allows developers to create scalable and maintainable applications with ease. When combined with GraphQL—a query language for APIs—it offers a powerful toolset for building efficient and flexible APIs. However, securing these APIs is paramount. In this article, we will explore how to build secure GraphQL APIs using NestJS with JWT (JSON Web Token) authentication.

What is NestJS?

NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. It uses TypeScript by default and embraces modular architecture, making it easy to manage and extend your application as it grows. NestJS supports various transport layers, including HTTP, WebSockets, and GraphQL, allowing developers to choose the best approach for their specific use case.

What is GraphQL?

GraphQL is an open-source data query and manipulation language for APIs, developed by Facebook. Unlike REST, which requires multiple endpoints to fetch related data, GraphQL allows clients to request precisely the data they need, reducing the amount of data transferred over the network and improving performance.

Why Use JWT for Authentication?

JWT (JSON Web Token) is a compact, URL-safe means of representing claims to be transferred between two parties. It allows you to verify the authenticity of the data and is widely used for authentication purposes. Using JWT for your GraphQL APIs allows you to:

  • Stateless Authentication: No need to store sessions on the server.
  • Cross-Domain Support: Easily integrate with applications hosted on different domains.
  • Scalability: Since JWTs can be verified without querying a database, they can easily scale across distributed systems.

Setting Up a NestJS Project

Step 1: Create a New NestJS Project

To get started, you need to have Node.js installed. Then, install the Nest CLI globally:

npm install -g @nestjs/cli

Create a new NestJS project:

nest new graphql-jwt-auth

Step 2: Install Required Dependencies

Navigate to your project directory and install the necessary packages:

cd graphql-jwt-auth
npm install @nestjs/graphql graphql-tools graphql apollo-server-express @nestjs/jwt @nestjs/passport passport passport-jwt

Creating a GraphQL API with JWT Authentication

Step 1: Configure GraphQL Module

Open app.module.ts and import the GraphQL module:

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: true,
    }),
    AuthModule,
  ],
})
export class AppModule {}

Step 2: Create Authentication Module

Generate the auth module:

nest g module auth
nest g service auth
nest g resolver auth

Step 3: Implement JWT Authentication

In auth.service.ts, implement the logic for JWT authentication:

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { User } from './user.entity'; // Assume you have a User entity

@Injectable()
export class AuthService {
  constructor(private readonly jwtService: JwtService) {}

  async login(user: User) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }

  validateUser(username: string, password: string): User {
    // Implement user validation logic here
  }
}

Step 4: Create a Login Resolver

In auth.resolver.ts, create a login resolver:

import { Resolver, Mutation, Args } from '@nestjs/graphql';
import { AuthService } from './auth.service';
import { LoginResponse } from './dto/login-response.dto'; // Create a DTO for the response

@Resolver()
export class AuthResolver {
  constructor(private readonly authService: AuthService) {}

  @Mutation(() => LoginResponse)
  async login(@Args('username') username: string, @Args('password') password: string) {
    const user = await this.authService.validateUser(username, password);
    return this.authService.login(user);
  }
}

Step 5: Set Up JWT Module

In auth.module.ts, set up the JWT module:

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { AuthResolver } from './auth.resolver';

@Module({
  imports: [
    JwtModule.register({
      secret: 'your-secret-key', // Replace with a secure key
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, AuthResolver],
})
export class AuthModule {}

Step 6: Protecting GraphQL Resolvers

To protect your GraphQL resolvers, you can use guards. Create a JWT guard in jwt-auth.guard.ts:

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

You can then apply this guard to your resolvers:

import { UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';

@Resolver()
export class SomeProtectedResolver {
  @UseGuards(JwtAuthGuard)
  @Query(() => User)
  async getProfile(@Context() context) {
    return context.user;
  }
}

Conclusion

Building secure GraphQL APIs with NestJS and JWT authentication is a powerful approach to modern application development. By leveraging the capabilities of NestJS and the flexibility of GraphQL, you can create APIs that are not only efficient but also secure. Implementing JWT authentication ensures that your API is protected, allowing only authorized users to access sensitive data.

As you develop your API, remember to follow best practices for security, such as using HTTPS, validating user input, and regularly updating your dependencies. With NestJS, you have a robust framework at your disposal to create scalable, maintainable, and secure applications. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.