i changed my code to include all of that and i send the state and now it won’t decode the session_token properly
i have this code here - it is able to decode it in const decodedPayload = jwt.decode(sessionToken);
, meaning the token is good and present, but is unable to verify it in the validateIncomingToken function:
CHECKOUT.TSX
import React from 'react';
import Stripe from 'stripe';
import queryString from 'query-string';
import jwt from 'jsonwebtoken'; // Import the JWT library
const MY_SECRET = '*****************'
const stripe = new Stripe('*****************************', {
apiVersion: '2022-11-15',
});
const Checkout = () => {
const priceId = '*******************';
const successUrl = 'https://**********************.us.auth0.com/continue';
const cancelUrl = 'https://www.********************.com/about';
async function createCheckoutSession() {
// Parse the URL to get state, session_token, customer_id, and redirect_uri
const parsedUrl = queryString.parse(window.location.search);
const sessionToken = parsedUrl.session_token as string;
const redirectUri = parsedUrl.redirect_uri;
const recievedState = parsedUrl.state;
const customerId = parsedUrl.customer_id as string;
const decodedPayload = jwt.decode(sessionToken);
console.log(decodedPayload);
const validateIncomingToken = () => {
if (!sessionToken) {
console.log('No session_token found');
}else{
console.log(sessionToken)
}
try {
const decoded = jwt.verify(sessionToken, MY_SECRET);
return decoded;
} catch (e:any) {
console.error('Error verifying session token:', e.message); // Log the error message for debugging
throw 'Invalid session_token';
}
};
const decodedData = validateIncomingToken()
const generateNewToken = (data: any, state: any) => {
const payload = {
sub: data.sub, // Mandatory, must match incoming token's sub
state,// Mandatory, validated by Auth0
}
// Even though iat and exp are not added above, they are implicitly added by the jwt library
const token = jwt.sign(payload, MY_SECRET, { expiresIn: '60s' })
return token
}
const newToken = generateNewToken(decodedData, recievedState)
// Check if the session_token, customer_id, and redirectUri exist
if (sessionToken && redirectUri && customerId) {
const newURI = `${successUrl}?state=${recievedState}&session_token=${newToken}`;
const session = await stripe.checkout.sessions.create({
customer: customerId,
payment_method_types: ['card'],
line_items: [{ price: priceId, quantity: 1 }],
subscription_data: {
trial_period_days: 5
},
mode: 'subscription',
success_url: newURI,
cancel_url: cancelUrl,
});
if (session.url) {
window.location.href = session.url; // Redirect to Stripe checkout page
}
}
}
return (
<div>
<br></br><br></br><br></br>
<button onClick={createCheckoutSession}>Click Here To Checkout For Our *********** Plan!</button>
</div>
);
};
the console decodes the full token, showing the
sub, exp, iat, etc.
and also logs the session_token
but throws these errors:
Error verifying session token: Right-hand side of 'instanceof' is not an object
(anonymous)
Uncaught (in promise) Invalid session_token
why is this and is there anything else i am missing
thanks again @thameera
btw the action code:
exports.onExecutePostLogin = async (event, api) => {
try {
const isPaid = event.user.app_metadata.isPaid;
if (event.stats.logins_count !== 1 && isPaid) {
return;
} else {
if (event.user.app_metadata.stripe_customer_id) {
const sessionToken = api.redirect.encodeToken({
secret: '***********************'
//expiresInSeconds: 60,
payload: {
email: event.user.email,
externalUserId: 1234,
},
});
console.log(sessionToken)
// Redirect the user to the Stripe checkout page with session_token query parameter
api.redirect.sendUserTo('https://www.*********************.com/checkout', {
query:
{
session_token: sessionToken,
customer_id: event.user.app_metadata.stripe_customer_id
},
});
}
}
} catch (error) {
console.log(error.message);
api.access.deny(
"We could not create your account, problem with stripe redirection.\n" +
"Please contact support for assistance."
);
}
};
exports.onContinuePostLogin = async (event, api, ) => {
try {
let payload;
payload = api.redirect.validateToken({
secret: '********************',
tokenParameterName: 'session_token',
});
// Check if the algorithm is correct
if (payload){
console.log('Token signature is valid');
// Now you can use the decoded token as needed
console.log(payload);
// Set the app metadata if needed
api.user.setAppMetadata('isPaid', true);
} else {
console.log('Invalid token signature');
}
} catch (error) {
console.log('Error receiving and validating the token and with using the continue endpoint');
return api.access.deny('Error occurred during redirect.');
}
};
(secrets are the same)
did i need to verify and sign the jwt token is that why it wasn’t working before and if so how do i get it to work and if the jwt token isn’t a problem, then what it is?