pub async fn token(
pool: Data<PgPool>,
__arg1: OAuthValidated<TokenQuery>,
req: HttpRequest,
app_conf: Data<ApplicationConfiguration>,
) -> ControllerResult<HttpResponse>Expand description
Handles the /token endpoint for exchanging authorization codes or refresh tokens.
This endpoint issues and rotates OAuth 2.0 and OpenID Connect tokens with support for PKCE, DPoP sender-constrained tokens, and ID Token issuance.
§Authorization Code Grant
- Validates client credentials (
client_id,client_secret) or public client rules. - Verifies the authorization code, its redirect URI, PKCE binding (
code_verifier), and expiration. - Optionally verifies a DPoP proof and binds the issued tokens to the DPoP JWK thumbprint (
dpop_jkt). - Issues a new access token, refresh token, and (for OIDC requests) an ID token.
§Refresh Token Grant
- Validates the refresh token and client binding.
- Verifies DPoP proof when applicable (must match the original
dpop_jkt). - Rotates the refresh token (revokes the old one, inserts a new one linked to it).
- Issues a new access token (and ID token if
openidscope requested).
§Security Features
- PKCE (RFC 7636): Enforced for public clients and optionally for confidential ones.
- DPoP (RFC 9449): Sender-constrains tokens to a JWK thumbprint.
- Refresh Token Rotation: Prevents replay by revoking old RTs on use.
- OIDC ID Token: Issued only if
openidis in the granted scopes.
Follows:
§Example
POST /api/v0/main-frontend/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=http://localhost&client_id=test-client-id&client_secret=test-secret&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXkSuccessful response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "DPoP",
"expires_in": 3600
}Example error:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": "invalid_client",
"error_description": "invalid client secret"
}Example DPoP error:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="use_dpop_proof", error_description="Missing DPoP header"