I am using Action flows and creating a redirect token, that is then validated upon a secondary call to /continue endpoint on my auth0 domain.
The initiating code is:
exports.onExecutePostLogin = async (event, api) => {
// Run only for the ASPSP SCA SPA client
if (event.client.client_id !== FRONTEND_CLIENT_ID) {
return;
}
if (event.authorization) {
// Strong customer authentication / SCA / MFA
const scopes = extractScopesFromEvent(event); // defined on top and works well
if (scopes.includes("sca:required")) {
// Create token
const session_token = api.redirect.encodeToken({
secret: event.secrets.REDIRECT_SECRET,
expiresInSeconds: 60,
payload: {
sub: event.user.user_id,
email: event.user.email,
continue_uri: `https://${AUTH0_DOMAIN}/continue`,
// state to be added here? <---------------------------- notice
},
});
// REDIRECT
var redirectUri = `${event.request.hostname}/callback/confirm`
if (event.transaction) {
redirectUri = `${event.transaction.redirect_uri}`
}
api.redirect.sendUserTo(redirectUri, {
query: {
session_token: session_token,
state: `over-ride`
}
});
}
}
// Add the Authentication Method Reference to amr custom claim
api.idToken.setCustomClaim(NAMESPACE + "amr", event.authentication?.methods);
return;
};
Without including the scope, the flow is simple and returns a token with the custom claim “amr” value with a {name:"pwd", time:"time"}
. When the scope sca:required
is used, I want to create a session_token and redirect the user to a custom web page before adding additional claims and authorizing them. The page on the redirection will give the user extra info (this is not relevant for my issue) and then call the /continue endpoint.
The redirectUri
parameter works well, and redirects me to http://localhost:3000/callback/confirm?session_token=<session_token>
The code on my custom application then sends this call via regular HTML :
consent: true
session_token: <session_token gotten from URI query param in the redirect>
state: <the state gotten from URI query param in the redirect>
The continue function is as follows:
exports.onContinuePostLogin = async (event, api) => {
const payload = api.redirect.validateToken({
secret: event.secrets.REDIRECT_SECRET,
tokenParameterName: 'session_token',
});
api.multifactor.enable("any", { allowRememberBrowser: false });
api.idToken.setCustomClaim(NAMESPACE + "amr", event.authentication?.methods);
api.idToken.setCustomClaim(NAMESPACE + "consent", payload.consent ?? "");
return;
};
The error I get is “The session token is invalid: State in the token does not match the /continue state”. I understand that I have not added a “state” in the payload of my session_token, but the documentation at Redirect with Actions states that " The code above will append a session_token
query string parameter to URL used in the redirect (in addition to the state
parameter that Auth0 will add automatically)". However it does not.
I have tried adding event.transaction?.state and also arbitrary values to the token, but the state parameter I get back in the redirect is automatically created (and can’t be overloaded, it seems), so what should I do here?
Thanks