Auth0 and Stripe Integration
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
- Auth0 Sign Up (Any Medium Works, e.g. User/Pass, SSO, Social, etc)
- Customer data hits onExecutePostLogin() action in Post Login Flow
- Generate Session Token with information from our web frontend passed along (e.g. cart_id, product_id, subscription_id, or w.e.)
- 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
- Redirect Customer to Stripe
- Payment success
- Redirect from Stripe to Auth0 /continue endpoint
- 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.
- On the Auth0 side, generate a session_token, state parameter and append to your tenant hostname.
- 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}
- For Stripe, generate a payment or checkout link with the necessary pricing information and post payment success_url encoded in the link.
- 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.
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.
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
Step 5. Serverless.yml Framework Deployment with Query String Parameter Validation
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
Step 9. onContinuePostLogin() method call on redirect from AWS API Gateway
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.







