Understanding Tokens in Node.js and NestJS 🚀
Tags: backend, nestjs, node, jwt
Published: 2024-06-13 04:52:04

Hey there, fellow devs! 👋 Today, we're diving into the world of tokens in Node.js and NestJS. Tokens are essential for securing our APIs and managing user sessions. Let's break down the most common types: **access tokens** and **refresh tokens**. Let's go! 🌟

## Access Tokens 🔑

Access tokens are like your VIP pass 🎟️ to the API. When you log in, the server gives you an access token, which you then use to access protected routes and resources.

### Key Points:
- **Short-lived**: Usually valid for a few minutes to an hour ⏳.
- **Stored in**: Browser storage (like localStorage) or HTTP-only cookies 🍪.
- **Usage**: Sent with each request (typically in the `Authorization` header as `Bearer <token>`).

### Example:
```javascript
// Example of using an access token in a request
fetch('https://api.example.com/protected', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your-access-token-here'
  }
})
.then(response => response.json())
.then(data => console.log(data));
```

## Refresh Tokens 🔄

Refresh tokens are your backstage pass 🎫. They let you get a new access token without re-authenticating. When your access token expires, use the refresh token to get a new one.

### Key Points:
- **Long-lived**: Valid for days, weeks, or even months 📆.
- **Stored in**: HTTP-only cookies or secure storage on the server 🔒.
- **Usage**: Sent to a specific endpoint to obtain a new access token.

### Example:
```javascript
// Example of using a refresh token to get a new access token
fetch('https://api.example.com/refresh-token', {
  method: 'POST',
  credentials: 'include' // Ensure cookies are sent with the request
})
.then(response => response.json())
.then(data => {
  const newAccessToken = data.accessToken;
  // Use the new access token as needed
});
```

## JWT (JSON Web Tokens) 📜

Both access and refresh tokens are often implemented as JWTs. JWTs are compact, URL-safe tokens that contain a set of claims (user info, token validity, etc.) and are signed by the server.

### Structure of a JWT:
1. **Header**: Contains the type of token and the signing algorithm.
2. **Payload**: Contains the claims (e.g., user ID, expiration time).
3. **Signature**: Verifies the token’s authenticity.

### Example of a JWT:
```json
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```

## Implementing Tokens in NestJS ⚙️

NestJS, with its robust module system, makes it straightforward to implement token-based authentication. Here’s a quick overview of how you might set it up:

### Step 1: Install Necessary Packages
```bash
npm install @nestjs/jwt @nestjs/passport passport passport-jwt
```

### Step 2: Configure JWT Module
```typescript
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    JwtModule.register({
      secret: 'yourSecretKey', // Change to a strong secret key
      signOptions: { expiresIn: '1h' }, // Access token validity
    }),
  ],
})
export class AuthModule {}
```

### Step 3: Create Auth Service
```typescript
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

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

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

  async generateRefreshToken(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return this.jwtService.sign(payload, { expiresIn: '7d' }); // Refresh token validity
  }
}
```

### Step 4: Protect Routes with Guards
```typescript
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add custom authentication logic here if needed
    return super.canActivate(context);
  }
}

// Apply the guard to your routes
@Controller('protected')
export class ProtectedController {
  @UseGuards(JwtAuthGuard)
  @Get()
  getProtectedResource() {
    return 'This is a protected resource!';
  }
}
```

And there you have it! 🎉 You’re now ready to implement token-based authentication in your Node.js and NestJS applications. Whether you’re using access tokens for quick, ephemeral access or refresh tokens for long-term sessions, tokens keep your app secure and user-friendly.

Happy coding! 💻✨