DEV Community

Cover image for Day 52: How to build a Split-Screen Login & Parse JWTs in AWS Lambda 🔐
Eric Rodríguez
Eric Rodríguez

Posted on

Day 52: How to build a Split-Screen Login & Parse JWTs in AWS Lambda 🔐

I hated the default Amazon Cognito login screen. It looked like a dashboard from 2015.

Today, I decided to build a custom Split-Screen Auth UI for my React app and update my AWS Lambda backend to actually read the JSON Web Tokens (JWT) sent by the frontend. Here is exactly how I did it.

  1. The Frontend: Split-Screen Auth with Amplify

Instead of using the standard wrapper which forces a centered card, I used Authenticator.Provider. This gives you access to the useAuthenticator hook so you can render the login form exactly where you want it.

I built a two-column layout using Tailwind CSS. Left side: Branding. Right side: Login.

import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';

const CustomAuthWrapper = () => {
const { authStatus } = useAuthenticator((context) => [context.authStatus]);

if (authStatus === 'authenticated') return ;

return (


{/* Left Column: Branding */}

FinAI Agent


  {/* Right Column: Auth Form */}
  <div className="w-1/2 flex items-center justify-center">
       <Authenticator />
  </div>
</div>

);
};

  1. Injecting the Bearer Token

To make the backend aware of who is calling it, we need to send the Cognito JWT. I updated my fetch calls in React to grab the session token dynamically:

JavaScript
import { fetchAuthSession } from 'aws-amplify/auth';

const { tokens } = await fetchAuthSession();
const jwtToken = tokens?.idToken?.toString();

const response = await fetch(API_URL, {
headers: { 'Authorization': Bearer ${jwtToken} }
});

  1. The Backend: Parsing JWT in Python (AWS Lambda)

API Gateway handles the heavy lifting of verifying the signature, but I still needed my Lambda function to know who the user was to query DynamoDB correctly. I wrote a small base64 decoding snippet to extract the sub (user ID) and email.

Python
import base64
import json

def lambda_handler(event, context):
headers = event.get('headers', {})
auth_header = headers.get('authorization', headers.get('Authorization', ''))

if auth_header.startswith('Bearer '):
    token = auth_header.split(' ')[1]
    payload_b64 = token.split('.')[1]
    payload_b64 += '=' * (-len(payload_b64) % 4) # Add padding

    payload = json.loads(base64.b64decode(payload_b64).decode('utf-8'))

    user_id = payload.get('sub')
    user_email = payload.get('email')

    print(f"Authenticated: {user_email} (ID: {user_id})")

My Serverless app is now officially Multi-Tenant! Every user gets their own DynamoDB sandbox, and the AI greets them by their real name. 🚀

Top comments (0)