UNPKG

sdk-simple-auth

Version:

Universal JavaScript/TypeScript authentication SDK with multi-backend support, automatic token refresh, and React integration

532 lines (428 loc) 11.6 kB
# 🚀 Quick Start Guide - SDK Simple Auth ## 📦 **Installation** ```bash npm install sdk-simple-auth ``` ## 🎯 **Setup in 3 Steps** ### **Step 1: Import and Configure** ```typescript import { AuthSDK } from 'sdk-simple-auth'; const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000' // Your authentication API }); ``` ### **Step 2: User Login** ```typescript async function loginUser() { try { const user = await auth.login({ email: 'user@example.com', password: 'my-password' }); console.log('✅ User authenticated:', user); // user = { id: 1, email: '...', name: '...', ... } } catch (error) { console.error('❌ Login error:', error.message); } } ``` ### **Step 3: Check State** ```typescript // Check if authenticated const isAuthenticated = await auth.isAuthenticated(); if (isAuthenticated) { const user = auth.getCurrentUser(); console.log('Current user:', user); } else { console.log('No active session'); } ``` ## 🔧 **Configuration by Backend Type** ### **🟢 Node.js + Express** If your backend is Node.js with Express and responds like this: ```json { "success": true, "data": { "user": { "id": 1, "email": "user@test.com", "name": "User" }, "token": "eyJhbGciOiJIUzI1NiIs...", "refreshToken": "refresh-token-here" } } ``` **Use:** ```typescript import { createQuickNodeAuth } from 'sdk-simple-auth'; const auth = createQuickNodeAuth('http://localhost:3000'); ``` ### **🟠 Laravel + Sanctum** If your backend is Laravel with Sanctum: ```json { "user": { "id": 1, "email": "user@test.com", "email_verified_at": "2025-01-01T00:00:00.000000Z", "created_at": "2025-01-01T00:00:00.000000Z" }, "token": "1|sanctum-token-here" } ``` **Use:** ```typescript import { createQuickSanctumAuth } from 'sdk-simple-auth'; const auth = createQuickSanctumAuth('http://localhost:8000/api'); // Login with device_name (required by Sanctum) const user = await auth.login({ email: 'user@example.com', password: 'password', device_name: 'my-web-app' }); ``` ### **🔵 Pure JWT** If your backend returns standard JWT: ```json { "access_token": "eyJhbGciOiJIUzI1NiIs...", "user": { "sub": "1", "email": "user@test.com", "name": "User" } } ``` **Use:** ```typescript import { AuthSDK } from 'sdk-simple-auth'; const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000', backend: { type: 'jwt-standard' } }); ``` ## ⚛️ **React Integration** ### **Basic Component** ```jsx import React, { useState, useEffect } from 'react'; import { AuthSDK } from 'sdk-simple-auth'; // Create SDK instance (outside component) const auth = new AuthSDK({ authServiceUrl: process.env.REACT_APP_API_URL }); function AuthExample() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // Check existing session checkExistingSession(); // Listen to state changes const unsubscribe = auth.onAuthStateChanged((state) => { setUser(state.user); setLoading(state.loading); }); return unsubscribe; // Cleanup }, []); const checkExistingSession = async () => { const isAuth = await auth.isAuthenticated(); if (isAuth) { setUser(auth.getCurrentUser()); } setLoading(false); }; const handleLogin = async () => { setLoading(true); try { const userData = await auth.login({ email: 'user@example.com', password: 'password123' }); // setUser updates automatically via onAuthStateChanged } catch (error) { alert('Login error: ' + error.message); } setLoading(false); }; const handleLogout = () => { auth.logout(); // setUser updates automatically via onAuthStateChanged }; if (loading) { return <div>Loading...</div>; } return ( <div> {user ? ( <div> <h1>Hello, {user.name || user.email}!</h1> <p>ID: {user.id}</p> <button onClick={handleLogout}>Logout</button> </div> ) : ( <div> <h1>You are not logged in</h1> <button onClick={handleLogin}>Login</button> </div> )} </div> ); } export default AuthExample; ``` ### **Custom Hook** ```jsx import { useState, useEffect } from 'react'; import { AuthSDK } from 'sdk-simple-auth'; const auth = new AuthSDK({ authServiceUrl: process.env.REACT_APP_API_URL }); export function useAuth() { const [state, setState] = useState({ user: null, loading: true, error: null, isAuthenticated: false }); useEffect(() => { const unsubscribe = auth.onAuthStateChanged((authState) => { setState({ user: authState.user, loading: authState.loading, error: authState.error, isAuthenticated: authState.isAuthenticated }); }); // Check initial session auth.isAuthenticated().then(isAuth => { if (isAuth) { setState(prev => ({ ...prev, user: auth.getCurrentUser(), isAuthenticated: true, loading: false })); } else { setState(prev => ({ ...prev, loading: false })); } }); return unsubscribe; }, []); const login = async (credentials) => { try { const user = await auth.login(credentials); return user; } catch (error) { throw error; } }; const logout = () => { auth.logout(); }; const getAuthHeaders = async () => { return await auth.getAuthHeaders(); }; return { ...state, login, logout, getAuthHeaders, auth // Direct access to SDK if needed }; } // Use the hook function MyComponent() { const { user, loading, login, logout, isAuthenticated } = useAuth(); if (loading) return <div>Loading...</div>; return ( <div> {isAuthenticated ? ( <div> <p>Welcome, {user.name}</p> <button onClick={logout}>Logout</button> </div> ) : ( <button onClick={() => login({ email: 'test@test.com', password: '123' })}> Login </button> )} </div> ); } ``` ## 🔄 **Token Management** ### **Auto Refresh** ```typescript // SDK automatically handles token refresh const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000', tokenRefresh: { enabled: true, bufferTime: 300, // Refresh 5 minutes before expiry maxRetries: 3 } }); // Get valid token (with auto refresh if needed) const token = await auth.getValidAccessToken(); // Ready-to-use headers const headers = await auth.getAuthHeaders(); // { Authorization: 'Bearer valid-token' } ``` ### **Use with Fetch/Axios** ```typescript // With native fetch async function apiCall() { const headers = await auth.getAuthHeaders(); const response = await fetch('/api/data', { headers: { 'Content-Type': 'application/json', ...headers } }); return response.json(); } // With axios import axios from 'axios'; // Interceptor to add token automatically axios.interceptors.request.use(async (config) => { const headers = await auth.getAuthHeaders(); config.headers = { ...config.headers, ...headers }; return config; }); // Interceptor to handle 401 errors axios.interceptors.response.use( (response) => response, async (error) => { if (error.response?.status === 401) { // Token expired, try refresh try { await auth.refreshTokens(); // Retry original request const headers = await auth.getAuthHeaders(); error.config.headers = { ...error.config.headers, ...headers }; return axios.request(error.config); } catch (refreshError) { // Refresh failed, logout auth.logout(); window.location.href = '/login'; } } return Promise.reject(error); } ); ``` ## 🛠️ **Debug and Troubleshooting** ### **Analyze Your API Response** ```typescript // If you don't know what format your backend uses auth.debugResponse(responseFromYourAPI); // This will print to console: // 🔍 API Response Debug // 📥 Original response: { ... } // ✅ Extracted tokens: { ... } // ✅ Extracted user: { ... } ``` ### **Check Token State** ```typescript // Debug current token auth.debugToken(); // Detailed session information const sessionInfo = await auth.getExtendedSessionInfo(); console.log({ isValid: sessionInfo.isValid, tokenType: sessionInfo.tokenType, expiresIn: sessionInfo.expiresIn, canRefresh: sessionInfo.canRefresh }); ``` ### **Backend Auto-detection** ```typescript import { quickAnalyzeAndCreate } from 'sdk-simple-auth'; // Make manual login to your API and pass the response const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@test.com', password: '123' }) }); const data = await response.json(); // SDK will analyze and configure automatically const auth = quickAnalyzeAndCreate(data, 'http://localhost:3000'); ``` ## ❌ **Common Errors and Solutions** ### **"No user information found"** **Problem:** Your API doesn't return user data where the SDK expects it. **Solution:** ```typescript const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000', backend: { userSearchPaths: ['user', 'data.user', 'profile'], // Where to search fieldMappings: { userId: ['id', 'user_id', 'userId'], email: ['email', 'mail'], name: ['name', 'username', 'full_name'] } } }); ``` ### **"Token invalid or expired"** **Problem:** Invalid token or incorrect configuration. **Solutions:** ```typescript // 1. Check token format auth.debugToken(); // 2. Check refresh capability const sessionInfo = await auth.getExtendedSessionInfo(); console.log('Can refresh:', sessionInfo.canRefresh); // 3. Configure refresh properly const auth = new AuthSDK({ // ... tokenRefresh: { enabled: true, bufferTime: 300 } }); ``` ### **CORS or Network Errors** **Problem:** Connection errors with the API. **Solution:** ```typescript // Custom HTTP client with error handling const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000', httpClient: { async post(url, data, config) { try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', ...config?.headers }, body: JSON.stringify(data) }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } return await response.json(); } catch (error) { console.error('HTTP Error:', error); throw error; } }, // ... other methods similarly } }); ``` ## 🎉 **Ready to Use!** With these examples you have everything needed to integrate `sdk-simple-auth` into your application. ### **Next Steps:** 1. ✅ **Install**: `npm install sdk-simple-auth` 2. ✅ **Configure** according to your backend 3. ✅ **Integrate** into your application 4. ✅ **Test** login/logout 5. ✅ **Customize** as needed ### **Additional Resources:** - 📚 [Complete examples](../examples/) - 🔧 [Advanced configuration](./advanced-config.md) - 🐛 [Troubleshooting](./troubleshooting.md) - 📖 [API Reference](./api-reference.md) Need help? [Open an issue](https://github.com/olivio-git/sdk-simple-auth/issues) in the repository.