Skip to content

Authentication

Vulcan uses JWT-based authentication. All API endpoints require authentication unless explicitly marked as public.

Endpoints

Login

Authenticates a user and returns a JWT token.

http
POST /api/auth/login

Request Body

json
{
  "email": "user@example.com",
  "password": "password123"
}

Success Response 200 OK

json
{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "expiresAt": "2026-01-13T10:00:00Z"
  },
  "error": null,
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "jkl-012"
  }
}

Error Response 401 Unauthorized

json
{
  "data": null,
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Invalid email or password"
  },
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "mno-345"
  }
}

Refresh Token

Refreshes an expired JWT token using a refresh token.

http
POST /api/auth/refresh

Request Body

json
{
  "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}

Success Response 200 OK

json
{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "expiresAt": "2026-01-13T10:00:00Z"
  },
  "error": null,
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "pqr-678"
  }
}

Error Response 401 Unauthorized

json
{
  "data": null,
  "error": {
    "code": "INVALID_REFRESH_TOKEN",
    "message": "Invalid or expired refresh token"
  },
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "stu-901"
  }
}

Logout

Invalidates the current session and refresh token.

http
POST /api/auth/logout

Headers

http
Authorization: Bearer <token>

Success Response 204 No Content

No response body.


Using Authentication

Request Header

Include the JWT token in the Authorization header for all authenticated requests:

http
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Token Expiration

  • Access tokens expire after 1 hour
  • Refresh tokens expire after 7 days
  • Use the refresh endpoint to get a new access token before expiration

Frontend Integration

typescript
// Using TanStack Query
export function useLogin() {
  return useMutation({
    mutationFn: (credentials: LoginRequest) =>
      authApi.login(credentials),
    onSuccess: (data) => {
      localStorage.setItem('token', data.token);
    },
  });
}

// API client interceptor
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

Security Best Practices

Important

  • Never store tokens in cookies without HttpOnly and Secure flags
  • Always use HTTPS in production
  • Implement token refresh before expiration
  • Clear tokens on logout
  • Handle 401 responses by redirecting to login

Built with VitePress | v1.1.0