When you deny a login with api.access.deny(...) many applications do not know how to handle the Auth0 500 with error_description. So, I would like to redirect to my own deny page.
Which of the following should I do? I do not want to user to be able to onContinuePostLogin after all, they have been DENIED access and should not be able to continue, should not have a session or token. Full-stop.
exports.onExecutePostLogin = async (event, api) => {
// No `return`, does code stop after this?
api.access.deny('Deny example.');
// Return
return api.access.deny('Deny example.');
// Deny PLUS redirect, is this even possible?
api.access.deny('Deny example.');
api.redirect.sendUserTo("https://my-app.exampleco.com");
// Found this on the forums, redirect to logout with return
api.redirect.sendUserTo("https://{auth0_tenant}.eu.auth0.com/v2/logout?returnTo=https%3A%2F%2Fmy-app.exampleco.com");
};
Do I need return? Can someone advise on the above code?
You should always return the api.access.deny() call. This ensures:
The action stops executing immediately
No token is issued
The denial is properly propagated
Trying to use api.redirect.sendUserTo() after api.access.deny() won’t work because:
The deny action terminates the authentication flow
Any code after the deny won’t execute
The redirect would never be reached
If you need custom error handling, you should handle this on the client side. Here’s how:
// In your NextJS app or whatever framwork you using. Customize accordiingly
const { handleRedirectCallback } = useAuth0();
try {
await handleRedirectCallback();
} catch (error) {
//Customize based on what you see in response also check for error_description in query param when auth0 redirect
if (error.error === 'access_denied' || error.error === 'unauthorized') {
// Redirect to your custom error page
router.push('/access-denied');
}
}
If you really need custom redirection on denial, you could use Auth0’s Error Pages customization:
Go to Auth0 Dashboard → Settings → Tenant Settings → General → Error Pages
Choose “Custom” error page
Set your URL (e.g., https://my-app.exampleco.com/access-denied)
This would handle all authentication errors, including denials from your Actions, in a more standard way.
The approach of redirecting to logout isn’t recommended because:
It’s unnecessary - no session was created to logout from
Thanks this is very helpful. The only reason redirecting to logout was appealing to me is that gave me fine-grained control over the returnUrl. For example I could have different access-denied pages PER client.
Regarding return api.access.deny(...) I wish I could just throw and control app flow through exceptions. I know this is generally a bad practice, but controlling flow through undefined/null is even uglier/harder. Consider the following code:
In the above code I have to pass “api” around to inner functions.
If I want to stop my process for whatever reason I essentially am just passing undefined (I assume deny() returns undefined) and then exiting the main parent function based on that.