Sitemap
Adam Kramer

Adam Kramer

Modern Software Developer and Entrepreneur

Auth0 and Stripe Integration

4 min readDec 12, 2023

--

Over at Blue Umbrella Software we recently ran into an integration conundrum and I wanted to share with the developer community our solution to the issue we encountered.

Preamble

If you are familiar with Auth0 you have likely ran across their flows and actions. Flows are logic pipelines used during different aspects of the authentication lifecycle. Actions are the logic used within a flow to provide a means to interrupt, validate, manipulate or otherwise layer your own internal business processes into the authentication lifecycle. We will focus on the Post Login/Login Flow and writing actions that enable Stripe integration for a checkout service (item, subscription, cart, and more)

Our Intended Process Flow

  1. Auth0 Sign Up (Any Medium Works, e.g. User/Pass, SSO, Social, etc)
  2. Customer data hits onExecutePostLogin() action in Post Login Flow
  3. Generate Session Token with information from our web frontend passed along (e.g. cart_id, product_id, subscription_id, or w.e.)
  4. Generate Stripe PaymentLink or Stripe Checkout Session Url with Auth0 Session information and Auth0 State parameter needed on the successful redirect from stripe to /continue the authentication flow
  5. Redirect Customer to Stripe
  6. Payment success
  7. Redirect from Stripe to Auth0 /continue endpoint
  8. Verify state and session information returned to ensure CRSF attacks are limited on both service endpoints

Technical Design

During our deployment Auth0 provides a means to encode data into a session_token and include that as a query string parameter when redirecting the customer (step 3).

We need to accomplish a few things to successfully redirect, pay and return to Auth0 to validate the auth session.

  1. On the Auth0 side, generate a session_token, state parameter and append to your tenant hostname.
  2. Our Auth0 redirect link would look something like this

const success_url = https://{tenant-name}.us.auth0.com/continue?session_token={session_token}&state={state}

  1. For Stripe, generate a payment or checkout link with the necessary pricing information and post payment success_url encoded in the link.
  2. Our Stripe redirect link would look something like this after generation

https://pay.stripe.com/{encoded-string-includes-auth0-success-url-redirect}

The Rub

Here in lies the issue. The Auth0 state parameter is generated AFTER you call api.redirect.sendUserTo(payment_url, { query: { session_token } }) not before. Therefore you cannot include it in the success_url of the payment or checkout url. Which would invalidate the /continue endpoint on the redirect from Stripe.

Get Adam Kramer’s stories in your inbox

Join Medium for free to get updates from this writer.

Another issue is that the session_token needs to be returned to the Auth0 /continue endpoint with the generated Auth0 state parameter included in it.

Our Solution

In order to solve this we introduce AWS API Gateway and Lambda as a redirection middleware. We moved the Stripe payment or checkout url generation to AWS Lambda and kept the Auth0 session_token and state generation in the on onExecutePostLogin() action.

What does this allow us to do? We can now capture the state and session_token query string parameters after they are generated from Auth0, include them in our Stripe payment or checkout url request, decode the session_token, insert the Auth0 state parameter and sign the payload for Auth0 to verify once payment has succeeded in the onContinuePostLogin() method call. That’s a lot of words. Maybe a diagram that outlines this help.

Press enter or click to view image in full size

As you can see in the diagram we are able to generate the payment or checkout url, redirect the customer to stripe, checkout, redirect back to lambda, sign the new session_token with necessary state parameter and continue on with our Auth0 session.

The code necessary to accomplish these tasks is below matching the steps in the process flow given above.

Step 1. From your application. I used react and the associated Auth0 library. Use whichever library works for your use case.

Press enter or click to view image in full size

Step 2, 3. Normal Social Login. I wont cover this part as its well documented in Auth0 website

Step 4. Calling the onExecutePostLogin() method within the Login Flow

Press enter or click to view image in full size
Example Auth0 onExecutePostLogin() Script with API Gateway Redirect

Step 5. Serverless.yml Framework Deployment with Query String Parameter Validation

Press enter or click to view image in full size
Serverless.yml Deployment Script

Step 6. The Lambda Code To Decode and Generate a Stripe Checkout Session

Step 7. Payment.

Step 8. The Lambda Code to Decode and Sign a New JWT Session Token with the original state and redirect

Press enter or click to view image in full size

Step 9. onContinuePostLogin() method call on redirect from AWS API Gateway

Press enter or click to view image in full size

I hope this helps someone as it took a little bit in figuring out the solution regarding what came first: Stripe Url or Auth0 Url. Turns out Auth0 Session Token with some Redirection Magic.

--

--

Adam Kramer
Adam Kramer

Modern Software Developer and Entrepreneur