top of page

Implementing Magic Link Authentication with AWS Cognito in a Ruby on Rails Application

  • Sampath Kumar
  • 6 days ago
  • 3 min read


AWS Cognito provides robust authentication and authorization capabilities but does not natively support Magic Link authentication. However, by utilizing custom authentication triggers, AWS Cognito can be extended to implement this functionality. In this blog post, we will explore the implementation using Ruby on Rails for the backend API and Node.js for AWS Lambda functions.


What is Magic Link Authentication?

Magic Link authentication is a passwordless login method where a user receives a unique, time-sensitive link via email. Clicking the link verifies their identity and grants access to the application. This method enhances security by eliminating password-related vulnerabilities associated with traditional password-based authentication.


User Authentication Flow

  1. User enters their email and clicks "Sign In".

  2. Rails API verifies the email against Cognito and generates a time-sensitive, encrypted token.

  3. Magic link is sent to the user's email with the token embedded in the URL.

  4. User clicks the link, and the token is sent back to the API for verification.

  5. Cognito custom authentication triggers (Lambda functions) validate the token.

  6. If valid, Cognito issues authentication tokens, and the user is granted access.


Steps to Implement Magic Link Authentication


1. Configure AWS Cognito User Pool

  1. Create a new User Pool in the Amazon Cognito Console.

  2. Enable email as a sign-in option.

  3. Add a custom attribute named magiclinkToken to store the generated token.

  4. Add an additional custom attribute named payloadToken to store a security token

  5. Configure Lambda triggers for custom authentication.

  6. For custom lambda function authentication, the below option should be enabled in Cognito App clients - Authentication flows - Sign in with custom authentication flows from Lambda triggers: ALLOW_CUSTOM_AUTH


2. Backend API in Ruby on Rails

When a user provides their email and clicks "Sign In," the Rails API performs the following steps:

  • Validate the email against Cognito.

  • Create a payload containing { email: user_email, expiry_time: timestamp, payloadToken: SecureRandom.hex(4) }.

  • Encrypt the payload and store it in the Cognito custom attributes magiclinkToken and payloadToken.

  • Send the magic link to the user via email.


3. AWS Lambda Functions for Custom Authentication

AWS Cognito requires three custom Lambda functions: DefineAuthChallenge, CreateAuthChallenge, and VerifyAuthChallengeResponse. These are implemented in Node.js.


DefineAuthChallenge (Determines if a user has successfully authenticated)

This function checks if a user exists and determines whether authentication should proceed. If the session is empty, a new authentication challenge is issued. If a previous attempt was successful, the user is authenticated.


CreateAuthChallenge (Generates and stores Magic Link token in Cognito)

This function generates the authentication challenge by retrieving the stored magiclinkToken from the user's attributes. The challenge token is included in the authentication flow so it can be verified later.


VerifyAuthChallengeResponse (Validates the Magic Link Token)

This function decrypts the token, verifies the email, checks expiration, and determines whether the challenge is correct. If the conditions match, authentication succeeds.


Decryption Utility (decryption.mjs)

This function decrypts the Magic Link token using AES-256-GCM encryption. It extracts the IV, auth tag, and encrypted data, then decrypts it using the shared key.


4. Handling the Magic Link Click

  • The frontend extracts the token from the link and sends it to the backend.

  • The backend verifies the token by calling Cognito’s respondToAuthChallenge API.

  • If valid, Cognito issues authentication tokens for the user.


Conclusion

By extending AWS Cognito with custom authentication triggers, we can implement Magic Link authentication securely and efficiently. This approach eliminates password-related vulnerabilities while providing a seamless login experience.

 
 
 

Comments


bottom of page