AUTHENTICATION SERVICE INTEGRATION GUIDE ========================================== This document is designed for use with LLM coding agents and AI assistants to understand how to integrate applications with the Authentication Service. Service URL: https://authreturn.com OVERVIEW -------- The Authentication Service provides third-party authentication for applications. It handles user signup, login, and token verification. Applications receive JWT tokens that can be verified locally (without HTTP requests) or via API endpoints. KEY CONCEPTS ------------ 1. JWT Tokens: JSON Web Tokens signed with HS256 algorithm. Tokens contain user_id, email, and expiration information. Tokens expire after 30 days. 2. Stateless Authentication: Tokens are self-contained and can be verified without database lookups. The signature proves the token was created by the auth service. 3. Two Verification Methods: - Local verification: Decode JWT with SECRET_KEY (no HTTP request needed) - API verification: Send token to /api/verify endpoint 4. CORS: All /api/* and /auth/* endpoints support cross-origin requests. API ENDPOINTS ------------- BASE URL: https://authreturn.com POST /api/signup Create a new user account. Request body (JSON): { "email": "user@example.com", "password": "password123" } Success response (201): { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": 1, "email": "user@example.com" } } Error response (409): { "error": "Email already exists" } Error response (400): { "error": "Email and password required" } or { "error": "Password must be at least 6 characters" } POST /api/login Login and receive a token. Request body (JSON): { "email": "user@example.com", "password": "password123" } Success response (200): { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": 1, "email": "user@example.com" } } Error response (401): { "error": "Invalid email or password" } GET /api/verify?token=TOKEN Verify a token and get user info. Success response (200): { "valid": true, "user": { "id": 1, "email": "user@example.com" } } Error response (401): { "valid": false, "error": "Token expired" } or { "valid": false, "error": "Invalid token" } POST /api/verify Verify a token (POST method). Request body (JSON): { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } Response: Same as GET /api/verify GET /api/user Get user info from token. Supports Authorization header or query parameter. Request with header: GET /api/user Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... Request with query: GET /api/user?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... Success response (200): { "id": 1, "email": "user@example.com" } Error response (401): { "error": "Invalid token" } POST /api/refresh Refresh a token if within 7 days of expiration. Request body (JSON): { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } Success response (200): { "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } Error response (401): { "error": "Invalid token" } REDIRECT-BASED AUTHENTICATION FLOW ----------------------------------- The service provides hosted login and signup pages that can redirect users back to your application with an authentication token. This is a simple redirect flow, not OAuth. GET /auth/login?redirect_uri=URL Redirect users to hosted login form, then redirect back with token. Example: https://authreturn.com/auth/login?redirect_uri=https://myapp.com/callback After login, user is redirected to: https://myapp.com/callback?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... GET /auth/signup?redirect_uri=URL Redirect users to hosted signup form, then redirect back with token. Example: https://authreturn.com/auth/signup?redirect_uri=https://myapp.com/callback After signup, user is redirected to: https://myapp.com/callback?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... TOKEN VERIFICATION METHODS --------------------------- METHOD 1: Local Verification (Recommended for Performance) JWT tokens can be verified locally without making HTTP requests. You need the SECRET_KEY from the authentication service. Contact the service administrator to obtain this key. Python Example: import jwt SECRET_KEY = "your-secret-key-from-auth-service" def verify_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return { 'valid': True, 'user_id': payload['user_id'], 'email': payload['email'] } except jwt.ExpiredSignatureError: return {'valid': False, 'error': 'Token expired'} except jwt.InvalidTokenError: return {'valid': False, 'error': 'Invalid token'} JavaScript Example (Node.js): const jwt = require('jsonwebtoken'); const SECRET_KEY = 'your-secret-key-from-auth-service'; function verifyToken(token) { try { const payload = jwt.verify(token, SECRET_KEY); return { valid: true, userId: payload.user_id, email: payload.email }; } catch (error) { return { valid: false, error: error.message }; } } METHOD 2: API Verification Make an HTTP request to the /api/verify endpoint: JavaScript Example: async function verifyToken(token) { const response = await fetch( 'https://authreturn.com/api/verify?token=' + encodeURIComponent(token) ); return await response.json(); } Python Example: import requests def verify_token(token): response = requests.get( 'https://authreturn.com/api/verify', params={'token': token} ) return response.json() INTEGRATION EXAMPLES --------------------- EXAMPLE 1: Direct API Integration (JavaScript) const AUTH_SERVICE_URL = 'https://authreturn.com'; async function signup(email, password) { const response = await fetch(AUTH_SERVICE_URL + '/api/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); const data = await response.json(); if (data.success) { localStorage.setItem('auth_token', data.token); return data.user; } throw new Error(data.error); } async function login(email, password) { const response = await fetch(AUTH_SERVICE_URL + '/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); const data = await response.json(); if (data.success) { localStorage.setItem('auth_token', data.token); return data.user; } throw new Error(data.error); } async function verifyToken(token) { const response = await fetch( AUTH_SERVICE_URL + '/api/verify?token=' + encodeURIComponent(token) ); return await response.json(); } function getAuthToken() { return localStorage.getItem('auth_token'); } function logout() { localStorage.removeItem('auth_token'); } EXAMPLE 2: Redirect-Based Authentication Flow (JavaScript) const AUTH_SERVICE_URL = 'https://authreturn.com'; function redirectToLogin(callbackUrl) { const authUrl = AUTH_SERVICE_URL + '/auth/login?redirect_uri=' + encodeURIComponent(callbackUrl); window.location.href = authUrl; } function redirectToSignup(callbackUrl) { const authUrl = AUTH_SERVICE_URL + '/auth/signup?redirect_uri=' + encodeURIComponent(callbackUrl); window.location.href = authUrl; } function handleAuthCallback() { const urlParams = new URLSearchParams(window.location.search); const token = urlParams.get('token'); if (token) { localStorage.setItem('auth_token', token); verifyToken(token).then(result => { if (result.valid) { console.log('Logged in as:', result.user.email); // Redirect to main app or update UI } else { console.error('Invalid token:', result.error); } }); } } EXAMPLE 3: Server-Side Token Verification (Python Flask) from flask import request, jsonify import jwt import functools import os import requests SECRET_KEY = os.getenv('AUTH_SERVICE_SECRET_KEY') AUTH_SERVICE_URL = 'https://authreturn.com' # Option A: Local verification (requires SECRET_KEY) def verify_token_local(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return { 'valid': True, 'user_id': payload['user_id'], 'email': payload['email'] } except jwt.ExpiredSignatureError: return {'valid': False, 'error': 'Token expired'} except jwt.InvalidTokenError: return {'valid': False, 'error': 'Invalid token'} # Option B: API verification (no SECRET_KEY needed) def verify_token_api(token): response = requests.get( AUTH_SERVICE_URL + '/api/verify', params={'token': token} ) return response.json() # Decorator to protect routes def require_auth(f): @functools.wraps(f) def decorated_function(*args, **kwargs): token = None # Check Authorization header if 'Authorization' in request.headers: auth_header = request.headers['Authorization'] if auth_header.startswith('Bearer '): token = auth_header.split(' ')[1] # Fallback to query parameter if not token: token = request.args.get('token') if not token: return jsonify({'error': 'Token required'}), 401 # Use local or API verification result = verify_token_local(token) # or verify_token_api(token) if not result['valid']: return jsonify({'error': result['error']}), 401 # Add user info to request context request.user_id = result['user_id'] request.user_email = result['email'] return f(*args, **kwargs) return decorated_function # Usage in route @app.route('/api/protected') @require_auth def protected_route(): return jsonify({ 'message': 'Access granted', 'user_id': request.user_id, 'user_email': request.user_email }) EXAMPLE 4: Server-Side Token Verification (Node.js/Express) const express = require('express'); const jwt = require('jsonwebtoken'); const axios = require('axios'); const SECRET_KEY = process.env.AUTH_SERVICE_SECRET_KEY; const AUTH_SERVICE_URL = 'https://authreturn.com'; // Option A: Local verification function verifyTokenLocal(token) { try { const payload = jwt.verify(token, SECRET_KEY); return { valid: true, userId: payload.user_id, email: payload.email }; } catch (error) { return { valid: false, error: error.message }; } } // Option B: API verification async function verifyTokenAPI(token) { try { const response = await axios.get(AUTH_SERVICE_URL + '/api/verify', { params: { token } }); return response.data; } catch (error) { return { valid: false, error: 'Verification failed' }; } } // Middleware to protect routes function requireAuth(req, res, next) { let token = null; // Check Authorization header const authHeader = req.headers['authorization']; if (authHeader && authHeader.startsWith('Bearer ')) { token = authHeader.split(' ')[1]; } // Fallback to query parameter if (!token) { token = req.query.token; } if (!token) { return res.status(401).json({ error: 'Token required' }); } // Use local or API verification const result = verifyTokenLocal(token); // or await verifyTokenAPI(token) if (!result.valid) { return res.status(401).json({ error: result.error }); } // Add user info to request req.userId = result.userId || result.user.id; req.userEmail = result.email || result.user.email; next(); } // Usage in route app.get('/api/protected', requireAuth, (req, res) => { res.json({ message: 'Access granted', userId: req.userId, userEmail: req.userEmail }); }); TOKEN STRUCTURE --------------- JWT tokens consist of three parts separated by dots: header.payload.signature Header (base64 encoded JSON): { "alg": "HS256", "typ": "JWT" } Payload (base64 encoded JSON): { "user_id": 1, "email": "user@example.com", "iat": 1234567890, "exp": 1237159890 } Signature: HMAC-SHA256(base64(header) + "." + base64(payload), SECRET_KEY) The token is readable (you can base64 decode header and payload), but the signature prevents tampering. Only tokens signed with the correct SECRET_KEY are valid. TOKEN EXPIRATION ---------------- - Tokens expire after 30 days from creation - Tokens can be refreshed if within 7 days of expiration - Use POST /api/refresh to get a new token - Always check token validity before trusting user identity ERROR HANDLING -------------- HTTP Status Codes: 200: Success 201: Created (signup) 400: Bad Request (missing parameters, invalid JSON) 401: Unauthorized (invalid credentials, invalid/expired token) 409: Conflict (email already exists) 500: Internal Server Error Error Response Format: { "error": "Error message description" } SECURITY CONSIDERATIONS ----------------------- 1. HTTPS: Always use HTTPS in production. Never send tokens over unencrypted connections. 2. Token Storage: Store tokens securely: - Web apps: Use httpOnly cookies when possible, or localStorage for client-side storage - Mobile apps: Use secure storage mechanisms (Keychain on iOS, Keystore on Android) - Server apps: Store in secure environment variables or encrypted storage 3. SECRET_KEY: If using local verification, keep the SECRET_KEY secure: - Never commit SECRET_KEY to version control - Use environment variables or secure configuration management - Share SECRET_KEY only with trusted applications that need local verification - If SECRET_KEY is compromised, all tokens become untrustworthy 4. Token Validation: Always validate tokens before trusting user identity: - Check token signature - Check token expiration - Verify token structure 5. Password Requirements: Minimum 6 characters. Consider enforcing stronger requirements in your application. 6. CORS: The service enables CORS for all /api/* and /auth/* endpoints. This allows cross-origin requests from any domain. In production, consider restricting CORS to specific domains if needed. BEST PRACTICES -------------- 1. Use local verification when possible for better performance (no HTTP request needed). 2. Implement token refresh logic to automatically refresh tokens before expiration. 3. Handle token expiration gracefully by redirecting to login or refreshing the token. 4. Store tokens securely and never expose them in URLs (except during the redirect callback flow where the token is passed as a query parameter). 5. Validate all user input on the server side, even if tokens are valid. 6. Log authentication events for security auditing. 7. Implement rate limiting on authentication endpoints to prevent brute force attacks. 8. Use HTTPS for all authentication-related requests. QUESTIONS OR ISSUES ------------------- If you need the SECRET_KEY for local token verification, contact the authentication service administrator. The SECRET_KEY is required for local verification but not needed if you use API verification. For integration support or questions, refer to the service documentation or contact the service administrator.