🔐 Authentication Guide
Prerequisites
- API key configured (see API Key Setup)
- BRDZ SDK installed and initialized
Overview
This guide covers complete user authentication including traditional login/register and Two-Factor Authentication (2FA) implementation.
Traditional Authentication
User Registration
import brdzSDK from 'anantla_sdk';
const auth = brdzSDK.auth;
// Register new user
const registerUser = async (userData) => {
try {
const result = await auth.registerUser({
email: 'newuser@example.com',
username: 'newuser',
client_alias: 'My App',
client_type: 'individual',
country_code: 'ID',
phone: '+628123456789'
});
console.log('Registration successful:', result);
return result;
} catch (error) {
console.error('Registration failed:', error);
throw error;
}
};
User Login
const loginUser = async (email, password) => {
try {
const result = await auth.loginUser(email, password);
// Check if 2FA is required
if (result.requires_2fa) {
console.log('2FA required for user:', result.user_id);
return {
success: false,
requires_2fa: true,
user_id: result.user_id,
message: '2FA verification required'
};
}
// Save JWT token for authenticated requests
localStorage.setItem('brdz_auth_token', result.token);
localStorage.setItem('user_id', result.user_id);
// Update SDK configuration
const config = brdzSDK.config;
config.setToken(result.token);
console.log('Login successful:', result);
return result;
} catch (error) {
console.error('Login failed:', error);
throw error;
}
};
Get User Profile
const getUserProfile = async (userId) => {
try {
const profile = await auth.getUserProfile(userId);
console.log('User profile:', profile);
return profile;
} catch (error) {
console.error('Failed to get profile:', error);
throw error;
}
};
Password Reset
const resetPassword = async (email) => {
try {
const result = await auth.forgotPassword(email);
console.log('Password reset email sent:', result);
return result;
} catch (error) {
console.error('Password reset failed:', error);
throw error;
}
};
Two-Factor Authentication (2FA)
Enable 2FA (User Settings)
const twofa = brdzSDK.twofa;
// Step 1: Generate QR Code for 2FA setup
const setup2FA = async () => {
try {
const setupResult = await twofa.setup();
console.log('2FA Setup Data:');
console.log('QR Code URL:', setupResult.qr_code_url);
console.log('Manual Entry Key:', setupResult.manual_entry_key);
// Display QR code to user for scanning with authenticator app
return setupResult;
} catch (error) {
console.error('2FA setup failed:', error);
throw error;
}
};
// Step 2: Enable 2FA after user scans QR code
const enable2FA = async (tokenFromApp) => {
try {
const result = await twofa.enable(tokenFromApp);
console.log('2FA enabled successfully:', result);
// 2FA is now active for this user
return result;
} catch (error) {
console.error('2FA enable failed:', error);
throw error;
}
};
// Check 2FA status
const check2FAStatus = async () => {
try {
const status = await twofa.getStatus();
console.log('2FA Status:', status);
return status.is_enabled;
} catch (error) {
console.error('Failed to check 2FA status:', error);
return false;
}
};
Login with 2FA
const loginWith2FA = async (email, password) => {
try {
// Step 1: Initial login
const loginResult = await auth.loginUser(email, password);
if (!loginResult.requires_2fa) {
// No 2FA required, login complete
localStorage.setItem('brdz_auth_token', loginResult.token);
localStorage.setItem('user_id', loginResult.user_id);
const config = brdzSDK.config;
config.setToken(loginResult.token);
return loginResult;
}
// Step 2: 2FA verification required
console.log('2FA verification required');
const userId = loginResult.user_id;
// Get 2FA token from user input (6-digit code from authenticator app)
const twoFactorCode = await getTwoFactorCodeFromUser(); // Your UI implementation
// Step 3: Complete login with 2FA
const completeResult = await auth.completeLoginWith2FA(userId, twoFactorCode);
// Save tokens
localStorage.setItem('brdz_auth_token', completeResult.token);
localStorage.setItem('user_id', userId);
// Update SDK configuration
const config = brdzSDK.config;
config.setToken(completeResult.token);
console.log('Login with 2FA successful:', completeResult);
return completeResult;
} catch (error) {
console.error('2FA login failed:', error);
throw error;
}
};
// Helper function - implement based on your UI
const getTwoFactorCodeFromUser = async () => {
// TODO: Implement your UI to get 6-digit code from user
// This could be a modal, prompt, or form input
return new Promise((resolve) => {
// Your implementation here
const code = prompt('Enter 6-digit code from authenticator app:');
resolve(code);
});
};
2FA Management
// Get backup codes (save these securely!)
const getBackupCodes = async (password) => {
try {
const codes = await twofa.getBackupCodes(password);
console.log('Backup codes:', codes);
// Display to user - they should save these securely
return codes;
} catch (error) {
console.error('Failed to get backup codes:', error);
throw error;
}
};
// Disable 2FA
const disable2FA = async (currentPassword, twoFactorCode) => {
try {
const result = await twofa.disable(twoFactorCode, currentPassword);
console.log('2FA disabled:', result);
return result;
} catch (error) {
console.error('Failed to disable 2FA:', error);
throw error;
}
};
// Verify 2FA code (for login)
const verify2FACode = async (userId, code) => {
try {
const result = await twofa.verifyLogin(userId, code);
return result;
} catch (error) {
console.error('2FA verification failed:', error);
throw error;
}
};
Complete Authentication Implementation
class AuthenticationManager {
constructor() {
this.isAuthenticated = false;
this.currentUser = null;
this.init();
}
async init() {
// Check if user is already logged in
const token = localStorage.getItem('brdz_auth_token');
const userId = localStorage.getItem('user_id');
if (token && userId) {
// Set token in SDK
const config = brdzSDK.config;
config.setToken(token);
try {
// Verify token is still valid
const profile = await brdzSDK.auth.getUserProfile(userId);
this.currentUser = profile;
this.isAuthenticated = true;
console.log('User already authenticated:', profile.username);
} catch (error) {
// Token expired or invalid
this.logout();
}
}
}
async register(userData) {
try {
const result = await brdzSDK.auth.registerUser(userData);
console.log('Registration successful');
return result;
} catch (error) {
throw this.handleAuthError(error);
}
}
async login(email, password) {
try {
const result = await brdzSDK.auth.loginUser(email, password);
if (result.requires_2fa) {
return {
success: false,
requires_2fa: true,
user_id: result.user_id
};
}
return this.completeLogin(result);
} catch (error) {
throw this.handleAuthError(error);
}
}
async loginWith2FA(userId, twoFactorCode) {
try {
const result = await brdzSDK.auth.completeLoginWith2FA(userId, twoFactorCode);
return this.completeLogin(result);
} catch (error) {
throw this.handleAuthError(error);
}
}
completeLogin(result) {
// Save authentication data
localStorage.setItem('brdz_auth_token', result.token);
localStorage.setItem('user_id', result.user_id);
// Update SDK configuration
const config = brdzSDK.config;
config.setToken(result.token);
// Update state
this.isAuthenticated = true;
this.currentUser = result.user;
console.log('Login completed successfully');
return result;
}
async setup2FA() {
if (!this.isAuthenticated) {
throw new Error('User must be logged in to setup 2FA');
}
try {
const setupResult = await brdzSDK.twofa.setup();
return setupResult;
} catch (error) {
throw this.handleAuthError(error);
}
}
async enable2FA(code) {
try {
const result = await brdzSDK.twofa.enable(code);
console.log('2FA enabled for user');
return result;
} catch (error) {
throw this.handleAuthError(error);
}
}
async check2FAStatus() {
try {
const status = await brdzSDK.twofa.getStatus();
return status.is_enabled;
} catch (error) {
console.error('Failed to check 2FA status');
return false;
}
}
logout() {
// Clear stored data
localStorage.removeItem('brdz_auth_token');
localStorage.removeItem('user_id');
// Clear SDK token
const config = brdzSDK.config;
config.setToken('');
// Update state
this.isAuthenticated = false;
this.currentUser = null;
console.log('User logged out');
}
handleAuthError(error) {
if (error.message.includes('Invalid credentials')) {
return new Error('Invalid email or password');
}
if (error.message.includes('User not found')) {
return new Error('Account not found');
}
if (error.message.includes('2FA required')) {
return new Error('Two-factor authentication required');
}
if (error.message.includes('Invalid 2FA')) {
return new Error('Invalid authenticator code');
}
return error;
}
getCurrentUser() {
return this.currentUser;
}
isLoggedIn() {
return this.isAuthenticated;
}
}
// Usage
const authManager = new AuthenticationManager();
Usage Examples
Basic Login Flow
// Initialize authentication manager
const authManager = new AuthenticationManager();
// Login attempt
try {
const result = await authManager.login('user@example.com', 'password123');
if (result.requires_2fa) {
// Show 2FA input form
const code = await getUserInput2FA(); // Your UI implementation
const finalResult = await authManager.loginWith2FA(result.user_id, code);
console.log('Login successful with 2FA');
} else {
console.log('Login successful');
}
} catch (error) {
console.error('Login failed:', error.message);
}
2FA Setup Flow
// User wants to enable 2FA in settings
const enable2FAForUser = async () => {
try {
// Step 1: Generate QR code
const setup = await authManager.setup2FA();
// Step 2: Show QR code to user
displayQRCode(setup.qr_code_url); // Your UI implementation
// Step 3: Wait for user to scan and enter code
const code = await getUserInput2FA(); // Your UI implementation
// Step 4: Enable 2FA
await authManager.enable2FA(code);
alert('2FA enabled successfully!');
} catch (error) {
alert('2FA setup failed: ' + error.message);
}
};
Security Best Practices
Security Guidelines
- Store JWT tokens securely in localStorage (or httpOnly cookies for SSR)
- Implement token refresh logic for long-lived applications
- Clear tokens on logout completely
- Validate tokens on app initialization
- Handle token expiration gracefully
- Use HTTPS only for all authentication flows
- Encourage 2FA usage for enhanced security
Error Handling
const handleAuthErrors = (error) => {
switch (error.message) {
case 'Invalid credentials':
return 'Email or password is incorrect';
case 'User not found':
return 'No account found with this email';
case '2FA required':
return 'Please enter your 2FA code';
case 'Invalid 2FA code':
return 'Invalid authenticator code. Please try again';
case 'Token expired':
return 'Session expired. Please login again';
default:
return 'Authentication failed. Please try again';
}
};
Next Steps
Continue with the remaining guides:
- ✅ API Key Setup - Complete
- ✅ Authentication - Complete
- Quickstart Tutorial - Build your first app
- React Integration - Frontend components
Need Help?
If you encounter issues:
- Email: contact@anantla.com
- Contact: BRDZ Contact Form