Authentication Guide - iamhelitha/3xui-api-client GitHub Wiki
Authentication Guide
✅ Status: Fully tested and working
This guide explains how to handle authentication with the 3x-ui API, including login responses, session management, and security best practices.
Table of Contents
- Login Response Structure
- Session Cookie Management
- Automatic Authentication
- Manual Authentication
- Session Persistence
- Security Considerations
- Troubleshooting
Login Response Structure
When you call the login method, the API returns both JSON data and HTTP headers with session information.
JSON Response
{
"success": true,
"msg": "",
"obj": null
}
Response Fields:
success
(boolean): Indicates if login was successfulmsg
(string): Human-readable status messageobj
(null): Additional data (typically null for login)
HTTP Headers
The authentication cookie is provided in the response headers:
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Set-Cookie: 3x-ui=MTczNTUyMzMyN3xEWDhFQVFMX2dBQUJFQUVRQUFCMV80QUFBUVp6ZEhKcGJtY01EQUFLVEU5SFNVNWZWVk5GVWhoNExYVnBMMlJoZEdGaVlYTmxMMjF2WkdWc0xsVnpaWExfZ1FNQkFRUlZjMlZ5QWYtQ0FBRUVBUUpKWkFFRUFBRUlWWE5sY201aGJXVUJEQUFCQ0ZCaGMzTjNiM0prQVF3QUFRdE1iMmRwYmxObFkzSmxkQUVNQUFBQUZQLUNFUUVDQVFWaFpHMXBiZ0VGWVdSdGFXNEF8y6Y2EKU4tk9ljoHdsA7Hb8TqYbZZclkP6EfZlCy1-bs=; Path=/; Expires=Mon, 30 Dec 2024 02:48:47 GMT; Max-Age=3600; HttpOnly
Vary: Accept-Encoding
Date: Mon, 30 Dec 2024 01:48:47 GMT
Content-Length: 74
Cookie Attributes:
- Name:
3x-ui
- Value: Base64 encoded session data
- Path:
/
(available for all routes) - Expires: Absolute expiration time
- Max-Age:
3600
seconds (1 hour) - HttpOnly: Prevents JavaScript access (security feature)
Session Cookie Management
Extracting Cookie Information
const ThreeXUI = require('3xui-api-client');
const client = new ThreeXUI('https://your-server.com', 'username', 'password');
try {
const loginResult = await client.login();
console.log('Login Response:', loginResult.data);
// Output: { success: true, msg: "Login Successfully", obj: null }
console.log('Session Cookie:', client.cookie);
// Output: 3x-ui=MTczNTUyMzMyN3xEWDhFQVFMX2dBQUJFQUVRQUFCMV80QUFBUVp6ZEhKcGJtY01EQUFLVEU5SFNVNWZWVk5GVWhoNExYVnBMMlJoZEdGaVlYTmxMMjF2WkdWc0xsVnpaWExfZ1FNQkFRUlZjMlZ5QWYtQ0FBRUVBUUpKWkFFRUFBRUlWWE5sY201aGJXVUJEQUFCQ0ZCaGMzTjNiM0prQVF3QUFRdE1iMmRwYmxObFkzSmxkQUVNQUFBQUZQLUNFUUVDQVFWaFpHMXBiZ0VGWVdSdGFXNEF8y6Y2EKU4tk9ljoHdsA7Hb8TqYbZZclkP6EfZlCy1-bs=
console.log('Full Headers:', loginResult.headers);
// Contains all response headers including Set-Cookie
} catch (error) {
console.error('Login failed:', error.message);
}
Cookie Parsing
function parseCookieDetails(cookieString) {
const parts = cookieString.split(';').map(part => part.trim());
const [nameValue] = parts;
const [name, value] = nameValue.split('=');
const details = {
name,
value,
attributes: {}
};
// Parse cookie attributes
parts.slice(1).forEach(part => {
if (part.includes('=')) {
const [key, val] = part.split('=');
details.attributes[key.toLowerCase()] = val;
} else {
details.attributes[part.toLowerCase()] = true;
}
});
return details;
}
// Usage
const cookieHeader = loginResult.headers['set-cookie'][0];
const cookieDetails = parseCookieDetails(cookieHeader);
console.log('Cookie Details:', cookieDetails);
/* Output:
{
name: "3x-ui",
value: "MTczNTUyMzMyN3xEWDhFQVFMX2dBQUJFQUVRQUFCMV80QUFBUVp6ZEhKcGJtY01EQUFLVEU5SFNVNWZWVk5GVWhoNExYVnBMMlJoZEdGaVlYTmxMMjF2WkdWc0xsVnpaWExfZ1FNQkFRUlZjMlZ5QWYtQ0FBRUVBUUpKWkFFRUFBRUlWWE5sY201aGJXVUJEQUFCQ0ZCaGMzTjNiM0prQVF3QUFRdE1iMmRwYmxObFkzSmxkQUVNQUFBQUZQLUNFUUVDQVFWaFpHMXBiZ0VGWVdSdGFXNEF8y6Y2EKU4tk9ljoHdsA7Hb8TqYbZZclkP6EfZlCy1-bs=",
attributes: {
path: "/",
expires: "Mon, 30 Dec 2024 02:48:47 GMT",
"max-age": "3600",
httponly: true
}
}
*/
Automatic Authentication
The client handles authentication automatically:
const client = new ThreeXUI('https://your-server.com', 'username', 'password');
// No need to call login() manually
// The client will authenticate automatically on first API call
const inbounds = await client.getInbounds();
// Subsequent calls use the stored session
const specificInbound = await client.getInbound(1);
How it works:
- First API call triggers automatic login
- Session cookie is extracted and stored
- Cookie is attached to all subsequent requests
- If session expires (401 error), client re-authenticates automatically
Manual Authentication
For more control over the authentication process:
const client = new ThreeXUI('https://your-server.com', 'username', 'password');
try {
// Manually trigger login
const loginResult = await client.login();
if (loginResult.data.success) {
console.log('✅ Authentication successful');
console.log('Session expires in 1 hour');
// Now make API calls
const inbounds = await client.getInbounds();
} else {
console.error('❌ Authentication failed:', loginResult.data.msg);
}
} catch (error) {
console.error('❌ Login error:', error.message);
}
Session Persistence
Server-Side Storage (Recommended)
Store session cookies securely on your server:
class PersistentThreeXUIClient {
constructor(baseURL, username, password, storage) {
this.client = new ThreeXUI(baseURL, username, password);
this.storage = storage; // Redis, Database, etc.
this.sessionKey = `3xui_session_${baseURL}`;
}
async ensureAuthenticated() {
// Try to restore existing session
const storedCookie = await this.storage.get(this.sessionKey);
if (storedCookie) {
this.client.cookie = storedCookie;
this.client.api.defaults.headers.Cookie = storedCookie;
// Test if session is still valid
try {
await this.client.getInbounds();
console.log('✅ Restored existing session');
return;
} catch (error) {
if (error.response?.status === 401) {
console.log('⚠️ Stored session expired, re-authenticating...');
await this.storage.delete(this.sessionKey);
}
}
}
// Login and store new session
const loginResult = await this.client.login();
if (loginResult.data.success) {
// Store session with 50-minute expiration (10 minutes before actual expiry)
await this.storage.set(this.sessionKey, this.client.cookie, 3000);
console.log('✅ New session created and stored');
}
}
async getInbounds() {
await this.ensureAuthenticated();
return this.client.getInbounds();
}
// Add other methods as needed
}
// Usage with Redis
const redis = require('redis').createClient();
const persistentClient = new PersistentThreeXUIClient(
'https://your-server.com',
'username',
'password',
redis
);
const inbounds = await persistentClient.getInbounds();
Database Storage Example
// Example using a database
class DatabaseSessionManager {
constructor(db) {
this.db = db;
}
async storeSession(serverUrl, cookie) {
const expiresAt = new Date(Date.now() + 3000 * 1000); // 50 minutes
await this.db.query(`
INSERT INTO sessions (server_url, cookie, expires_at, created_at)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
cookie = VALUES(cookie),
expires_at = VALUES(expires_at),
updated_at = NOW()
`, [serverUrl, cookie, expiresAt, new Date()]);
}
async getSession(serverUrl) {
const result = await this.db.query(`
SELECT cookie FROM sessions
WHERE server_url = ? AND expires_at > NOW()
`, [serverUrl]);
return result.length > 0 ? result[0].cookie : null;
}
async deleteSession(serverUrl) {
await this.db.query('DELETE FROM sessions WHERE server_url = ?', [serverUrl]);
}
}
Security Considerations
1. Cookie Security
- HttpOnly: Prevents XSS attacks (already set by 3x-ui)
- Secure transmission: Always use HTTPS in production
- Storage: Never store cookies in client-side storage (localStorage, sessionStorage)
2. Session Management
class SecureSessionManager {
constructor(client) {
this.client = client;
this.sessionStartTime = null;
this.maxSessionAge = 3000 * 1000; // 50 minutes
}
async login() {
const result = await this.client.login();
this.sessionStartTime = Date.now();
return result;
}
isSessionExpired() {
if (!this.sessionStartTime) return true;
return (Date.now() - this.sessionStartTime) > this.maxSessionAge;
}
async ensureValidSession() {
if (this.isSessionExpired()) {
console.log('Session expired, re-authenticating...');
await this.login();
}
}
}
3. Credential Protection
// Environment variables for credentials
require('dotenv').config();
const client = new ThreeXUI(
process.env.THREEXUI_URL,
process.env.THREEXUI_USERNAME,
process.env.THREEXUI_PASSWORD
);
// Never hardcode credentials in your code!
// ❌ BAD
// const client = new ThreeXUI('https://server.com', 'admin', 'password123');
// ✅ GOOD
// Use environment variables or secure configuration management
Troubleshooting
Common Authentication Issues
1. Login Failed - Invalid Credentials
try {
await client.login();
} catch (error) {
if (error.message.includes('Login failed')) {
console.error('❌ Check your username and password');
console.error('❌ Ensure the user has admin privileges');
}
}
2. Session Expired
// The client handles this automatically, but you can detect it:
try {
const inbounds = await client.getInbounds();
} catch (error) {
if (error.response?.status === 401) {
console.log('Session expired, client will re-authenticate automatically');
}
}
3. Connection Issues
try {
await client.login();
} catch (error) {
if (error.code === 'ECONNREFUSED') {
console.error('❌ Cannot connect to server - check URL and network');
} else if (error.code === 'ENOTFOUND') {
console.error('❌ DNS resolution failed - check server URL');
} else if (error.response?.status === 404) {
console.error('❌ Login endpoint not found - check 3x-ui version');
}
}
4. Cookie Issues
// Check if cookie was received
const loginResult = await client.login();
if (!client.cookie) {
console.error('❌ No session cookie received');
console.log('Headers:', loginResult.headers);
} else {
console.log('✅ Session cookie stored:', client.cookie.substring(0, 20) + '...');
}
Debugging Authentication
// Enable detailed logging
class DebugThreeXUIClient extends ThreeXUI {
async login() {
console.log('🔐 Attempting login...');
try {
const result = await super.login();
console.log('✅ Login successful');
console.log('📄 Response:', result.data);
console.log('🍪 Cookie:', this.cookie ? 'Received' : 'Not received');
return result;
} catch (error) {
console.error('❌ Login failed:', error.message);
if (error.response) {
console.error('📄 Response data:', error.response.data);
console.error('📊 Status code:', error.response.status);
}
throw error;
}
}
}
const debugClient = new DebugThreeXUIClient('https://server.com', 'user', 'pass');
await debugClient.login();
Navigation
Previous | Next |
---|---|
← Home | Inbound Management → |
Related Documentation
- Inbound Management - VPN server configuration
- Client Management - User account operations
- Traffic Management - Data monitoring & control
- System Operations - Admin operations
Last updated: January 2025