Skip to main content
This guide explains how to authenticate users using JWT tokens with HTTP-only cookies. The authentication system automatically creates a TRON wallet for each new user.

Authentication Flow

The API uses JWT tokens stored in HTTP-only cookies:
  • Access Token: Short-lived token for API requests (stored in accessToken cookie)
  • Refresh Token: Long-lived token for refreshing access tokens (stored in refreshToken cookie)

User Registration

Register a new user account and automatically create a TRON wallet.

Endpoint

POST /api/auth/register

Request Body

{
  "email": "[email protected]",
  "username": "johndoe",
  "password": "SecurePassword123",
  "passwordConfirm": "SecurePassword123"
}

Validation Rules

  • All fields are required
  • Password must be at least 8 characters
  • Password and passwordConfirm must match
  • Email must be unique and valid format
  • Username must be unique and at least 3 characters

Response

{
  "message": "User registered successfully",
  "user": {
    "id": "507f1f77bcf86cd799439011",
    "email": "[email protected]",
    "username": "johndoe",
    "role": "user",
    "wallet": {
      "address": "TYwXGhKhqPTbLvRPFdvZnXqcqN4kVy7ABC",
      "balance": 0
    }
  }
}
The response sets two HTTP-only cookies: accessToken and refreshToken. These cookies are automatically sent with subsequent requests.

Implementation Example

const response = await fetch('http://localhost:3000/api/auth/register', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  credentials: 'include', // Important: Include cookies
  body: JSON.stringify({
    email: '[email protected]',
    username: 'johndoe',
    password: 'SecurePassword123',
    passwordConfirm: 'SecurePassword123'
  })
});

const data = await response.json();
console.log(data.user);

User Login

Authenticate an existing user with email and password.

Endpoint

POST /api/auth/login

Request Body

{
  "email": "[email protected]",
  "password": "SecurePassword123"
}

Response

{
  "message": "Login successful",
  "user": {
    "id": "507f1f77bcf86cd799439011",
    "email": "[email protected]",
    "username": "johndoe",
    "role": "user",
    "wallet": "TYwXGhKhqPTbLvRPFdvZnXqcqN4kVy7ABC"
  }
}

Implementation Example

const response = await fetch('http://localhost:3000/api/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  credentials: 'include',
  body: JSON.stringify({
    email: '[email protected]',
    password: 'SecurePassword123'
  })
});

const data = await response.json();

Get User Profile

Retrieve the authenticated user’s profile information.

Endpoint

GET /api/auth/profile
This endpoint requires authentication. The access token cookie must be present.

Response

{
  "user": {
    "id": "507f1f77bcf86cd799439011",
    "email": "[email protected]",
    "username": "johndoe",
    "role": "user",
    "wallet": "TYwXGhKhqPTbLvRPFdvZnXqcqN4kVy7ABC",
    "createdAt": "2024-01-15T10:30:00.000Z",
    "lastLogin": "2024-01-20T14:22:00.000Z"
  }
}

Refresh Access Token

Generate a new access token using the refresh token when the access token expires.

Endpoint

POST /api/auth/refresh

Response

{
  "message": "Token refreshed"
}

Implementation Example

const response = await fetch('http://localhost:3000/api/auth/refresh', {
  method: 'POST',
  credentials: 'include'
});

if (response.ok) {
  // New access token is set in cookie
  console.log('Token refreshed successfully');
}

Logout

Log out the current user and clear authentication cookies.

Endpoint

POST /api/auth/logout

Response

{
  "message": "Logout successful"
}

Implementation Example

const response = await fetch('http://localhost:3000/api/auth/logout', {
  method: 'POST',
  credentials: 'include'
});

const data = await response.json();
console.log(data.message);
Authentication cookies are configured with the following settings from src/api/auth/register.js:5:
const COOKIE_OPTIONS = {
  httpOnly: true,                              // Prevents JavaScript access
  secure: process.env.NODE_ENV === 'production', // HTTPS only in production
  sameSite: 'strict',                          // CSRF protection
  maxAge: 7 * 24 * 60 * 60 * 1000             // 7 days
};

Complete Authentication Flow

1

Register or Login

Call /api/auth/register or /api/auth/login with credentials. The server sets accessToken and refreshToken cookies.
2

Make Authenticated Requests

Include credentials: 'include' (fetch) or withCredentials: true (axios) in all API requests. The cookies are automatically sent.
3

Handle Token Expiration

When you receive a 401 error, call /api/auth/refresh to get a new access token, then retry the original request.
4

Logout

Call /api/auth/logout to clear cookies and end the session.

Error Handling

class AuthService {
  async login(email, password) {
    try {
      const response = await fetch('http://localhost:3000/api/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email, password })
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error);
      }

      return await response.json();
    } catch (error) {
      console.error('Login failed:', error.message);
      throw error;
    }
  }

  async refreshToken() {
    try {
      const response = await fetch('http://localhost:3000/api/auth/refresh', {
        method: 'POST',
        credentials: 'include'
      });

      if (!response.ok) {
        throw new Error('Token refresh failed');
      }

      return true;
    } catch (error) {
      console.error('Refresh failed:', error.message);
      return false;
    }
  }

  async logout() {
    await fetch('http://localhost:3000/api/auth/logout', {
      method: 'POST',
      credentials: 'include'
    });
  }
}

Build docs developers (and LLMs) love