Skip to content

Social Sign-in Guide (Google / GitHub)

This guide explains how to enable Google and GitHub authentication for the ChatKcal application.

Architecture Context

  • Backend: Resources (Cognito User Pool, AppSync, DynamoDB) are managed via AWS SAM (template.yaml).
  • Frontend: A standalone Vite React application that uses the AWS Amplify JavaScript Libraries (aws-amplify) and UI components (@aws-amplify/ui-react).
    • Note: The frontend is not managed by SAM, nor do we use the Amplify CLI (amplify add auth) to provision resources.
    • We manually connect the frontend to the backend by configuring Amplify.configure() in frontend/src/App.jsx using the outputs from the SAM deployment.

1. Configure Social Providers in AWS Cognito

Because we use SAM (Infrastructure as Code), we cannot use Amplify CLI commands to add social providers. You must configure them in the AWS Cognito service, either via the AWS Console (easiest for managing secrets like Client IDs) or by updating template.yaml.

  1. Go to the Amazon Cognito Console and select your User Pool (e.g., CalorieTrackerUserPool...).

  2. App Integration tab (or App client settings / Domain name):

    • Domain name: Ensure a domain prefix is set (e.g., chatkcal-auth-<random>).
    • This is required for the OAuth flow (hosted UI callbacks).
  3. Sign-in experience tab (or Social and external providers):

    • Identity providers:
      • Google:
        1. Create Project:
          • Go to Google Cloud Console.
          • Click the project dropdown (top left) -> New Project.
          • Name it "ChatKcal" (or similar) and create it.
        2. OAuth Consent Screen:
          • Navigate to APIs & Services -> OAuth consent screen.
          • Select External user type (unless using Google Workspace internally).
          • Fill in: App Name ("ChatKcal"), User Support Email, and Developer Contact Info.
          • Click Save and Continue (skip Scopes and Test Users for now).
        3. Create Credentials:
          • Go to APIs & Services -> Credentials.
          • Click Create Credentials -> OAuth client ID.
          • Application type: Select "Web application".
          • Name: "ChatKcal Cognito".
          • Authorized JavaScript origins: Paste your Cognito domain URL.
          • Format: https://<your-domain-prefix>.auth.<region>.amazoncognito.com
          • Authorized redirect URIs: Paste your Cognito domain URL + /oauth2/idpresponse.
          • Format: https://<your-domain-prefix>.auth.<region>.amazoncognito.com/oauth2/idpresponse
          • Find this: In Cognito Console -> App Integration -> Domain name.
          • Click Create.
        4. Copy Secrets:
          • Copy the Client ID and Client Secret.
        5. Configure Cognito:
          • Back in AWS Cognito Console, paste these into the Google provider configuration.
          • Scope: profile email openid
      • GitHub:
        • Cognito does not have a native "GitHub" button like Google.
        • You must add it as an OIDC Provider or use a bridge/wrapper.
        • Simpler Alternative: Stick to Google/Apple/Amazon for the standard Authenticator social buttons.
  4. App Integration tab -> App client list:

    • Select your client (CalorieTrackerAppClient).
    • Locate Managed login pages configuration (or "Hosted UI") and click Edit.
    • Identity Providers: Select Google (and others you added).
    • OAuth 2.0 Grant Types: Select Authorization code grant.
    • OpenID Connect scopes: Select email, openid, profile.
    • Callback URLs: Add both local and prod URLs:
      • http://localhost:5173/
      • https://<your-production-url>/
    • Sign-out URLs:
      • http://localhost:5173/
      • https://<your-production-url>/
    • Save changes.

Option B: Via SAM (template.yaml)

You can define AWS::Cognito::UserPoolIdentityProvider resources in template.yaml.

  • Warning: This requires storing OAuth Client Secrets (from Google/Facebook) in AWS Secrets Manager or Parameter Store to avoid committing them to git. For this project, Option A (Console) is often preferred for simplicity.

2. Frontend Integration (Amplify)

Since the frontend is not auto-generated by the Amplify CLI, we must manually ensure it knows about the OAuth configuration if we want full integration.

Update frontend/src/App.jsx

  1. Amplify Config: Ensure your Amplify.configure call includes the loginWith or oauth settings if required by your specific flow, though often the Authenticator component handles the redirect logic if the User Pool is correctly set up.

    However, the simplest way with the Authenticator UI component is just to enable the buttons:

  2. Authenticator Component: Locate the <Authenticator> usage in AppContent.

    Only add providers to socialProviders that you have fully configured in the Cognito Console. Adding 'google' without configuring Google in Cognito will result in an error when the user clicks the button.

    <Authenticator
      socialProviders={['google', 'apple', 'amazon', 'facebook']} // Add providers you configured in Cognito
      loginMechanisms={['email']}
      signUpAttributes={['email']}
      // ... other props
    />
    

3. User Identity & Account Linking

  • The Challenge: By default, if a user signs up with "email/password" and later signs in with Google (using the same email), Cognito creates two separate users (different sub IDs).

  • The Solution: We have deployed a Pre-SignUp Lambda Trigger (functions/pre_signup/app.py).

    • Logic: When a user signs in via an External Provider (Google), the Lambda checks for an existing "Native" (Email/Password) user with the same email.

    • Action: If a match is found, it automatically links the Google identity to the existing Native user.

    • Result: The user logs into the same account (same sub) regardless of the method used, preserving their data.

4. Verify Redirects

If you get a redirect_mismatch error:

  1. Check the URL in the browser address bar during the error.
  2. Ensure that exact URL (excluding the code=... part) is listed in the Callback URLs of your Cognito App Client settings.
  3. Ensure http://localhost:5173/ (trailing slash matters!) matches exactly what the application sends.