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
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
Request Body
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
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
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
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);
Cookie Configuration
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
Register or Login
Call /api/auth/register or /api/auth/login with credentials. The server sets accessToken and refreshToken cookies.
Make Authenticated Requests
Include credentials: 'include' (fetch) or withCredentials: true (axios) in all API requests. The cookies are automatically sent.
Handle Token Expiration
When you receive a 401 error, call /api/auth/refresh to get a new access token, then retry the original request.
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'
});
}
}