I was written a post about .NET Authentication and Authorization: dotnet Authentication and Authorization, and there are somethings I did not mention, that is how to handle Authentication failures.

The Authentication configuartion we mentioned before, that is a cookie policy:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromDays(30);
    options.SlidingExpiration = true;
});

But, the problem is, it will replies a 302 state code while Authentication failures, and the new location is /Account/Login by default. and notice the new address domain is the backend's domain, that is mean if we separated the app into frontend and backend, it will not redirects to a correct address when Authentication failures.

For example:

Assumes our frontend app listening address localhost:8800, and backend app listening localhost:9900, frontend request API but triggered authentication and be failure, responses 302 state code with location localhost:9900/Account/Login, frontend will automatically request this new address and found that is not a available API. Normally it should redircets to a login page, but frontend used http API like fetch or Axios, they will automatically request that new location while 302 response, and then would be failure.

Unfortunately we cannot change the domain of the new location.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromDays(30);
    options.SlidingExpiration = true;
		//  this is not allowed
    options.LoginPath = "https://domain.com/login";
});

One of the solution that I used is responses another state code that we can handle it manually like 401 that indicates unauthorized.

However we need a controller that the new location will redirects to, like the default login path below:

[Route("{controller}")]
public class AccountController : ControllerBase
{
    [HttpGet("Login")]
    public IActionResult ToLoginPage()
    {
        return Unauthorized();
    }

}

You can see it return a 401. And the frontend http API will received it and found it is 401, we can handle it, make it redirects to the login page we have.

e.g, I used Axios with interceptor:

export const req = axios.create({});

req.interceptors.response.use(
  function (response) {
    if (response.status === 401) {
      location.href = "/login";
    }
    return response;
  },
  function (error) {
    console.error("ERROR! - ", error);
    return Promise.reject(error);
  }
);