Back to Home

Integration Guide

Add authentication to your app using AuthReturn and AWS Cognito.

Quick Start

1. Include the Script

The auth component automatically loads its CSS and the Cognito SDK, so you only need one script tag:

<!-- Auth Component (auto-loads CSS and Cognito SDK) -->
<script src="https://authreturn.com/static/auth_component.js"></script>

<!-- Optional: Header Component for login/logout buttons -->
<script src="https://authreturn.com/static/auth_header_component.js"></script>
<link rel="stylesheet" href="https://authreturn.com/static/auth_header_component.css">

2. Add Container HTML

<!-- Modal for login/signup forms -->
<div id="auth-modal" class="auth-modal" style="display: none;">
    <div class="auth-modal-backdrop"></div>
    <div class="auth-modal-content">
        <button class="auth-modal-close" onclick="closeModal()">&times;</button>
        <div id="auth-container"></div>
    </div>
</div>

3. Initialize the Component

const APP_ID = 1;  // Your app ID from AuthReturn

function showAuthModal(mode) {
    AuthComponent.create({
        containerId: 'auth-container',
        mode: mode,  // 'login' or 'signup'
        appId: APP_ID,
        theme: 'dark',  // 'light' or 'dark' (default: 'light')
        onSuccess: (token, user) => {
            // user contains: { email, userId }
            localStorage.setItem('auth_token', token);
            localStorage.setItem('user_email', user.email);
            document.getElementById('auth-modal').style.display = 'none';
            // Refresh your UI here
        },
        onError: (error) => {
            console.error('Auth error:', error);
        }
    });
    document.getElementById('auth-modal').style.display = 'flex';
}

function closeModal() {
    document.getElementById('auth-modal').style.display = 'none';
}

AuthComponent.create() Options

OptionTypeDefaultDescription
containerIdstringrequiredID of the container element
modestring'login''login' or 'signup'
appIdnumbernullYour app ID (fetches Cognito config automatically)
cognitoConfigobjectnullDirect Cognito config: { userPoolId, clientId, region }
authReturnUrlstring'https://authreturn.com'AuthReturn server URL
themestring'light''light' or 'dark'
onSuccessfunctionnullCallback: (token, user) => {}
onErrorfunctionnullCallback: (errorMessage) => {}

Either appId or cognitoConfig is required. If using appId, Cognito config is fetched from AuthReturn automatically.

Header Component

The header component manages login/logout buttons and shows user state:

<div class="header-actions" id="auth-header-container">
    <button class="auth-header-login-btn">Sign In</button>
    <button class="auth-header-signup-btn">Sign Up</button>
    <div class="auth-header-user-info" style="display: none;">
        <span class="auth-header-user-email"></span>
        <button class="auth-header-logout-btn">Sign Out</button>
    </div>
</div>

<script>
const authHeader = AuthHeader.create({
    containerId: 'auth-header-container',
    authServiceUrl: 'https://authreturn.com',
    appId: 1,
    onLoginClick: (e) => { e.preventDefault(); showAuthModal('login'); },
    onSignupClick: (e) => { e.preventDefault(); showAuthModal('signup'); },
    onLogout: () => {
        // Your app cleanup - AuthHeader already clears localStorage
    }
});

// Returned object has methods:
// authHeader.getUser()   - returns current user or null
// authHeader.checkAuth() - re-check auth state
// authHeader.updateUI()  - manually refresh UI
</script>

AuthHeader.create() Options

OptionTypeDefaultDescription
containerIdstringrequiredID of the container element
authServiceUrlstring'https://authreturn.com'AuthReturn server URL
appIdnumbernullYour app ID
cognitoConfigobjectnullDirect Cognito config: { userPoolId, clientId }
onLoginClickfunctionnullClick handler for login button
onSignupClickfunctionnullClick handler for signup button
onLogoutfunctionnullCallback after logout completes

Automatic State Sync

The AuthHeader component automatically stays in sync with auth state changes:

Backend 401 Errors

When your backend returns 401 (expired token), dispatch the event to keep AuthHeader in sync:

if (response.status === 401) {
    localStorage.removeItem('auth_token');
    localStorage.removeItem('user_email');
    window.dispatchEvent(new CustomEvent('authreturn:authchange'));
    // Show login UI...
}

CSS Classes and Theming

The auth component uses these CSS classes for styling:

ClassDescription
.auth-formMain form container (max-width: 400px)
.auth-theme-lightLight theme modifier
.auth-theme-darkDark theme modifier
.auth-form-groupInput field wrapper
.auth-input-wrapperInput with password toggle
.auth-password-toggleShow/hide password button
.auth-submit-btnSubmit button
.auth-errorError message display
.auth-successSuccess message display
.auth-toggleLogin/signup toggle link
.auth-brandingFooter branding

Token Handling

Cognito ID Tokens Expire After 1 Hour

Your app must handle 401 errors and refresh tokens. The Cognito SDK handles this automatically if you use getSession().

Refreshing Tokens

async function getValidToken() {
    const ACI = window.AmazonCognitoIdentity;
    if (!ACI) return localStorage.getItem('auth_token');

    // Get your app's Cognito config
    const configRes = await fetch('https://authreturn.com/api/apps/YOUR_APP_ID/cognito');
    const config = await configRes.json();

    const userPool = new ACI.CognitoUserPool({
        UserPoolId: config.userPoolId,
        ClientId: config.clientId
    });

    const cognitoUser = userPool.getCurrentUser();
    if (!cognitoUser) return null;

    return new Promise((resolve) => {
        cognitoUser.getSession((err, session) => {
            if (err || !session?.isValid()) {
                resolve(null);
                return;
            }
            const newToken = session.getIdToken().getJwtToken();
            localStorage.setItem('auth_token', newToken);
            resolve(newToken);
        });
    });
}

Making Authenticated API Calls

async function apiCall(url, options = {}) {
    const token = await getValidToken();
    if (!token) {
        showAuthModal('login');
        throw new Error('Not authenticated');
    }

    const res = await fetch(url, {
        ...options,
        headers: {
            ...options.headers,
            'Authorization': `Bearer ${token}`
        }
    });

    if (res.status === 401) {
        // Token expired and couldn't refresh
        localStorage.removeItem('auth_token');
        localStorage.removeItem('user_email');
        window.dispatchEvent(new CustomEvent('authreturn:authchange'));
        showAuthModal('login');
        throw new Error('Session expired');
    }

    return res;
}

Backend Token Verification

Verify Cognito JWTs on your backend using the JWKS endpoint:

Python Example

import jwt
import requests
from functools import lru_cache

@lru_cache(maxsize=1)
def get_cognito_keys(region, user_pool_id):
    url = f'https://cognito-idp.{region}.amazonaws.com/{user_pool_id}/.well-known/jwks.json'
    return requests.get(url).json()['keys']

def verify_cognito_token(token, region, user_pool_id, client_id):
    keys = get_cognito_keys(region, user_pool_id)

    # Get the key ID from the token header
    header = jwt.get_unverified_header(token)
    key = next((k for k in keys if k['kid'] == header['kid']), None)
    if not key:
        raise ValueError('Key not found')

    # Construct the public key and verify
    public_key = jwt.algorithms.RSAAlgorithm.from_jwk(key)
    payload = jwt.decode(
        token,
        public_key,
        algorithms=['RS256'],
        audience=client_id,
        issuer=f'https://cognito-idp.{region}.amazonaws.com/{user_pool_id}'
    )
    return payload  # Contains 'email', 'sub', etc.

Password Reset

The auth component includes a "Forgot password?" link that triggers Cognito's password reset flow. Users receive an email with a verification code.

Custom Email Domain

By default, password reset emails come from AWS. Contact us to configure emails from your own domain via SES.

Security Best Practices

Troubleshooting

USER_SRP_AUTH is not enabled

Your Cognito user pool client needs SRP auth enabled. Contact AuthReturn support.

Token verification fails

Ensure you're using the correct userPoolId and clientId from /api/apps/{id}/cognito.

CORS errors

The auth component makes requests directly to AWS Cognito, which handles CORS. If you see CORS errors, check your network - the Cognito SDK may not be loaded.

See Architecture Overview for how AuthReturn works under the hood.