feat(dpop): provide nonce on immediate login

provide the DPoP nonce via cookie on login, this reduce the amount of API call
and prevent having any first call returning in 401
This commit is contained in:
Edouard Vanbelle
2026-08-09 14:40:10 +02:00
parent 2eb1e8a1d5
commit 950c8c0f38
9 changed files with 155 additions and 1 deletions
@@ -439,6 +439,14 @@ pub async fn login(
state.core.config.auth.refresh_token_expiry_secs,
);
cookie_auth::append_csrf_cookie(response.headers_mut(), auth_response.expires_in);
// Seed the SPA's DPoP-nonce cache so the first bound request
// after login doesn't eat a `use_dpop_nonce` challenge → retry.
// No-op when `dpop_mode = off`.
cookie_auth::maybe_append_dpop_nonce_cookie(
response.headers_mut(),
&state.dpop_nonce_service,
state.core.config.auth.dpop_mode,
);
// Diagnostic: warn when Secure cookies are set but the request
// arrived over plain HTTP, the browser will reject them (#241).
@@ -604,6 +612,12 @@ pub async fn refresh_token(
state.core.config.auth.refresh_token_expiry_secs,
);
cookie_auth::append_csrf_cookie(response.headers_mut(), auth_response.expires_in);
// Seed the SPA's DPoP-nonce cache — see the login handler above.
cookie_auth::maybe_append_dpop_nonce_cookie(
response.headers_mut(),
&state.dpop_nonce_service,
state.core.config.auth.dpop_mode,
);
Ok(response)
}
@@ -1797,6 +1811,12 @@ pub async fn oidc_exchange(
state.core.config.auth.refresh_token_expiry_secs,
);
cookie_auth::append_csrf_cookie(response.headers_mut(), auth_response.expires_in);
// Seed the SPA's DPoP-nonce cache — see the login handler above.
cookie_auth::maybe_append_dpop_nonce_cookie(
response.headers_mut(),
&state.dpop_nonce_service,
state.core.config.auth.dpop_mode,
);
Ok(response)
}