The Revoke Endpoint
The /token/revoke endpoint is a back channel endpoint that revokes an existing token.
INFO
- Implementing this endpoint is optional
- This endpoint requires
TokenRepository#getByAccessTokento be defined if usingtoken_type_hint=access_token
app.post("/token/revoke", async (req: Express.Request, res: Express.Response) => {
try {
const oauthResponse = await authorizationServer.revoke(req);
return handleExpressResponse(res, oauthResponse);
} catch (e) {
handleExpressError(e, res);
return;
}
});Configure
Client credentials authentication is enabled by default. To disable, set authenticateRevoke to false.
const authoriztionServer = new AuthorizationServer(
...,
{
authenticateRevoke: false,
}
);Request
A complete token revocation request will include the following parameters:
- token (required): The token to be revoked
- token_type_hint (optional): A hint about the type of the token submitted for revocation. Valid values are:
access_token,refresh_token,auth_code. The hint is purely advisory — the server identifies the token's type from the token itself, so refresh tokens are revoked even when the hint is absent or wrong. An unrecognized hint is rejected withunsupported_token_type.
The request must be authenticated with the requesting client's own credentials (client_id, plus client_secret for confidential clients). Any client may revoke its own tokens — the client does not need to be authorized for the client_credentials grant.
A presented JWT is revoked only if its signature verifies against the server's configured JwtService; a forged or unverifiable token is silently ignored (still a 200, per RFC 7009 §2.2). An expired access token can still be revoked — useful for killing its associated refresh token. With useOpaqueRefreshTokens enabled, opaque refresh token strings are resolved through TokenRepository#getByRefreshToken and revoke like any other token.
View sample revoke request
You can authenticate by passing the client_id and client_secret as a query string, or through basic auth.
POST /token/revoke HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
token=xxxxxxxxxx
&token_type_hint=refresh_token
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxxPOST /token/revoke HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic MTpzdXBlci1zZWNyZXQtc2VjcmV0
token=xxxxxxxxxx
&token_type_hint=refresh_tokenWhen authenticateRevoke = false:
new AuthorizationServer(..., {
authenticateRevoke: false,
})POST /token/revoke HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
token=xxxxxxxxxx
&token_type_hint=refresh_tokenResponse
The authorization server will respond with:
- An HTTP 200 (OK) status code if the token was successfully revoked, or if the submitted token is invalid, unknown, expired, or malformed. Per RFC 7009 §2.2 an invalid token is not an error. A 200 is also returned when an authenticated client submits a token it does not own — the token is left untouched, which avoids leaking token validity to other clients.
- An HTTP 401 (Unauthorized) status code with an
invalid_clienterror if client authentication fails — a missing or invalidclient_id, a wrongclient_secret, or a confidential client that presents no secret. Per RFC 7009 §2.1 a failed client authentication is refused with an RFC 6749 §5.2 error response, even though an invalid token is not. - An HTTP 400 (Bad Request) status code if the request is otherwise invalid or malformed (for example, an unsupported
token_type_hint).
The response body is empty for a 200. For error responses the server includes the OAuth 2.0 error fields.
A failed client authentication is a 401, not a silent 200
Distinguish the two failure modes: an invalid token (with valid or disabled client authentication) returns 200, but a failed client authentication returns 401 invalid_client. A client that fails to authenticate therefore receives an error rather than a misleading success — do not read a 200 as confirmation that authentication succeeded.
Supports the following RFCs