CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-aws-amplify--auth

Authentication category of AWS Amplify providing APIs and building blocks for creating authentication experiences with Amazon Cognito

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

oauth-social-authentication.mddocs/

OAuth & Social Authentication

OAuth/OIDC integration for social and enterprise identity providers including Google, Facebook, Amazon, Apple, and SAML/OIDC providers.

Enable OAuth Listener

Enable automatic handling of OAuth callback flows in your application. This is a side-effect import that sets up event listeners for OAuth completion.

// Import to enable OAuth callback handling
import "@aws-amplify/auth/enable-oauth-listener";

This import should be done once in your application, typically in your main application file or in a module that loads early. It automatically handles the OAuth redirect callback and completes the authentication flow.

Sign In With Redirect

Initiate OAuth/OIDC authentication flow using browser redirect.

function signInWithRedirect(input?: SignInWithRedirectInput): Promise<void>;

interface SignInWithRedirectInput {
  provider?: AuthProvider | {
    custom: string;
  };
  customState?: string;
  options?: {
    preferPrivateSession?: boolean;
  };
}

type AuthProvider = 'Google' | 'Facebook' | 'Amazon' | 'Apple';

Usage Example

import { signInWithRedirect } from "@aws-amplify/auth";

// Sign in with Google
await signInWithRedirect({
  provider: 'Google'
});

// Sign in with Facebook
await signInWithRedirect({
  provider: 'Facebook'
});

// Sign in with custom OIDC provider
await signInWithRedirect({
  provider: { custom: 'MyOIDCProvider' }
});

// Sign in with custom state for tracking
await signInWithRedirect({
  provider: 'Google',
  customState: 'user-journey-tracking-id'
});

Handle OAuth Callback

After OAuth redirect, handle the authentication result:

import { signInWithRedirect, getCurrentUser } from "@aws-amplify/auth";

// Check if user is signed in after OAuth redirect
async function handleOAuthCallback() {
  try {
    const user = await getCurrentUser();
    console.log("OAuth sign in successful:", user.username);
    return user;
  } catch (error) {
    console.log("OAuth sign in failed or user not signed in");
    throw error;
  }
}

// Call this after OAuth redirect
handleOAuthCallback().then(user => {
  // Redirect to app dashboard or handle success
  window.location.href = '/dashboard';
}).catch(error => {
  // Handle OAuth error or show sign-in form again
  console.error('OAuth authentication failed:', error);
});

OAuth Provider Configuration

Social Providers

Configure social providers in your Cognito User Pool:

// Provider configurations (set in AWS Console or CDK/CloudFormation)
const socialProviders = {
  Google: {
    client_id: 'your-google-client-id.apps.googleusercontent.com',
    client_secret: 'your-google-client-secret', // Server-side only
    authorize_scopes: ['email', 'profile', 'openid'],
    redirect_uri: 'https://yourapp.com/auth/callback'
  },
  
  Facebook: {
    client_id: 'your-facebook-app-id',
    client_secret: 'your-facebook-app-secret', // Server-side only
    authorize_scopes: ['email', 'public_profile'],
    redirect_uri: 'https://yourapp.com/auth/callback'
  },
  
  Amazon: {
    client_id: 'amzn1.application-oa2-client.your-client-id',
    client_secret: 'your-amazon-client-secret', // Server-side only
    authorize_scopes: ['profile'],
    redirect_uri: 'https://yourapp.com/auth/callback'
  },
  
  Apple: {
    client_id: 'com.yourcompany.yourapp',
    key_id: 'your-apple-key-id',
    private_key: 'your-apple-private-key', // Server-side only
    team_id: 'your-apple-team-id',
    authorize_scopes: ['email', 'name'],
    redirect_uri: 'https://yourapp.com/auth/callback'
  }
};

Custom OIDC Provider

For enterprise OIDC providers:

// Custom OIDC provider configuration
const customOIDCProvider = {
  provider_name: 'MyOIDCProvider',
  provider_type: 'OIDC',
  issuer_url: 'https://auth.company.com',
  client_id: 'your-oidc-client-id',
  client_secret: 'your-oidc-client-secret', // Server-side only
  authorize_scopes: ['openid', 'email', 'profile'],
  redirect_uri: 'https://yourapp.com/auth/callback',
  // Optional mappings
  attribute_mapping: {
    email: 'email',
    given_name: 'first_name',
    family_name: 'last_name',
    name: 'full_name'
  }
};

// Use in sign in
await signInWithRedirect({
  provider: { custom: 'MyOIDCProvider' }
});

OAuth Flow Patterns

Basic OAuth Flow

import { signInWithRedirect, getCurrentUser } from "@aws-amplify/auth";

class OAuthManager {
  async initiateOAuth(provider: AuthProvider) {
    // Store current location for post-auth redirect
    localStorage.setItem('preAuthLocation', window.location.pathname);
    
    // Initiate OAuth flow
    await signInWithRedirect({ provider });
  }
  
  async handleOAuthCallback() {
    try {
      // Check if user is now signed in
      const user = await getCurrentUser();
      
      // Get stored location
      const redirectTo = localStorage.getItem('preAuthLocation') || '/dashboard';
      localStorage.removeItem('preAuthLocation');
      
      // Redirect to intended destination
      window.location.href = redirectTo;
      
      return user;
    } catch (error) {
      // OAuth failed, redirect to sign-in
      window.location.href = '/sign-in?error=oauth_failed';
      throw error;
    }
  }
}

// Usage
const oauthManager = new OAuthManager();

// In your sign-in component
const handleGoogleSignIn = () => {
  oauthManager.initiateOAuth('Google');
};

// In your OAuth callback handler (usually on app load)
window.addEventListener('load', () => {
  // Check if this might be an OAuth callback
  const urlParams = new URLSearchParams(window.location.search);
  if (urlParams.has('code') || urlParams.has('state')) {
    oauthManager.handleOAuthCallback();
  }
});

State Parameter Usage

Use custom state for tracking user journey or preventing CSRF:

import { signInWithRedirect } from "@aws-amplify/auth";

// Generate secure state parameter
function generateSecureState() {
  const array = new Uint8Array(32);
  crypto.getRandomValues(array);
  return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
}

// Store state and context
const state = generateSecureState();
const context = {
  returnUrl: '/premium-signup',
  source: 'pricing-page',
  timestamp: Date.now()
};

localStorage.setItem(`oauth_state_${state}`, JSON.stringify(context));

// Initiate OAuth with custom state
await signInWithRedirect({
  provider: 'Google',
  customState: state
});

// In callback handler, validate state
function validateOAuthState(receivedState: string) {
  const contextKey = `oauth_state_${receivedState}`;
  const storedContext = localStorage.getItem(contextKey);
  
  if (!storedContext) {
    throw new Error('Invalid OAuth state');
  }
  
  const context = JSON.parse(storedContext);
  localStorage.removeItem(contextKey);
  
  // Check timestamp for expiry (e.g., 10 minutes)
  if (Date.now() - context.timestamp > 10 * 60 * 1000) {
    throw new Error('OAuth state expired');
  }
  
  return context;
}

Error Handling

OAuth authentication can fail for various reasons:

import { signInWithRedirect, AuthError } from "@aws-amplify/auth";

async function handleSocialSignIn(provider: AuthProvider) {
  try {
    await signInWithRedirect({ provider });
  } catch (error) {
    if (error instanceof AuthError) {
      switch (error.name) {
        case 'InvalidParameterException':
          console.log('Invalid provider configuration');
          break;
        case 'NotAuthorizedException':
          console.log('OAuth provider not configured');
          break;
        case 'UserNotConfirmedException':
          console.log('User email not confirmed');
          break;
        default:
          console.log('OAuth sign in failed:', error.message);
      }
    }
    
    // Handle OAuth-specific errors from URL parameters
    const urlParams = new URLSearchParams(window.location.search);
    const oauthError = urlParams.get('error');
    
    if (oauthError) {
      switch (oauthError) {
        case 'access_denied':
          console.log('User denied OAuth permission');
          break;
        case 'invalid_request':
          console.log('Invalid OAuth request');
          break;
        case 'server_error':
          console.log('OAuth provider server error');
          break;
        default:
          console.log('OAuth error:', oauthError);
      }
    }
  }
}

Best Practices

Security Considerations

  • Always use HTTPS for OAuth redirects
  • Validate state parameters to prevent CSRF attacks
  • Store sensitive OAuth configuration server-side
  • Use secure random state generation
  • Implement proper error handling and user feedback

User Experience

  • Provide clear loading states during OAuth flow
  • Handle OAuth cancellation gracefully
  • Store intended destination for post-auth redirect
  • Show appropriate error messages for OAuth failures
  • Consider progressive enhancement for browsers without JavaScript

Configuration Management

  • Use environment-specific OAuth configurations
  • Store OAuth secrets securely (environment variables, secrets manager)
  • Configure appropriate OAuth scopes for your application needs
  • Test OAuth flows in both development and production environments

docs

authentication-lifecycle.md

device-management.md

index.md

multi-factor-authentication.md

oauth-social-authentication.md

password-management.md

server-side-apis.md

session-management.md

user-management.md

webauthn-credentials.md

tile.json