Changelog
Guides

Call the API from a browser

Send cookies and CSRF tokens from a browser client, and set up CORS when the client runs on another origin.

Browser clients on the cookie stack and the JWT stack depend on cookies and antiforgery tokens. Follow these steps for a single-page app (SPA) or any other browser client.

Send cookies on every request

Add credentials: 'include' to every fetch call. With Axios, set withCredentials: true. Without it, the browser does not send the application cookie, the antiforgery cookie, the ReAuth cookie, or the JWT refresh cookie.

Send a CSRF token on protected requests

  1. Get a token. The cookie stack serves it at GET /identity/csrfToken. The JWT stack serves it at GET /auth/csrfToken. Both return { "csrfToken": "..." } and set the antiforgery cookie.
  2. Send the token in the RequestVerificationToken header on every route that requires antiforgery.
  3. If a request returns 400 with the body Invalid or missing CSRF token., get a new token and retry once.
async function csrf() {
  const r = await fetch('/identity/csrfToken', { credentials: 'include' });
  return (await r.json()).csrfToken;
}

const csrfToken = await csrf();
await fetch('/identity/manage/info', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json', 'RequestVerificationToken': csrfToken },
  body: JSON.stringify({ newEmail })
});

The token is tied to the signed-in user. After sign-in or sign-out, get a new token. Login, register, forgot password, and reset password need no token. The full list is in Antiforgery (CSRF) rules.

Set up CORS when the client runs on another origin

AuthEndpoints does not configure CORS. If the browser client and the API have different origins, add a CORS policy in the host that allows credentials and the AuthEndpoints headers:

builder.Services.AddCors(o => o.AddPolicy("spa", policy => policy
    .WithOrigins("https://app.example.com")
    .AllowCredentials()
    .AllowAnyMethod()
    .WithHeaders("Content-Type", "RequestVerificationToken", "X-AuthEndpoints-Reauth")));

var app = builder.Build();
app.UseCors("spa");
app.UseAuthEndpoints();

AllowCredentials does not work with AllowAnyOrigin. List the exact origins.

Keep the client and the API on the same site

CORS lets the request through, but cookie SameSite rules decide which cookies the browser sends:

CookieSameSite
.AspNetCore.Identity.ApplicationLax (Identity default)
AuthEndpoints.ReAuthStrict
AuthEndpoints.Jwt.RefreshTokenStrict

app.example.com and api.example.com are the same site, so these cookies work. A client on a different registrable domain, such as example-app.com calling example.com, is cross-site. The browser does not send Lax or Strict cookies on cross-site fetch calls. Serve the API under the same site as the client, or put a reverse proxy in front of it.