Deny PLUS redirect in Action Triggers

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?

The most correct and complete approach would be:

exports.onExecutePostLogin = async (event, api) => {
  return api.access.deny('Deny example.');
};

Here’s why:

  1. 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
  1. 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
  1. 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:

  1. Go to Auth0 Dashboard → Settings → Tenant Settings → General → Error Pages
  2. Choose “Custom” error page
  3. 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:

  1. 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:

const apiResult = CallAPI(api);
if (!apiResult) {
        return;
}


function CallAPI(api) {
    try {
        const apiResult = fetch(...);
        if (apiResult) {
            return { customerData: 'blah' };
        } else {
            return  api.access.deny("Bad customer.");
        }
    }
    catch (err) {
            return api.access.deny("External API call failed.");
    }
}

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.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.