Authorization ‐ OAuth2 ‐ Tuto 5 ‐ Token Refresh Flow with refreshTokenRoute - demingongo/kaapi GitHub Wiki
Token Refresh Flow with refreshTokenRoute
The refreshTokenRoute() method defines the behavior of the token endpoint for the Refresh Token Grant in OAuth2 and OpenID Connect flows using the @kaapi/oauth2-auth-design package.
It is available in all flow builders that support refresh tokens, namely:
- ✅ Authorization Code Flow
- ✅ Device Authorization Flow
- ❌ Not available for Client Credentials Flow (refresh tokens are not supported)
🔧 Route Configuration
The route can be customized using the following methods:
| Method | Description |
|---|---|
setPath(path) |
Defines the token endpoint path. Should match the one used in tokenRoute() for consistency. Default: /oauth2/token |
generateToken(fn) |
Core method where you implement the logic for validating the refresh token and issuing a new access token. |
🧩 generateToken() Overview
The generateToken() handler is responsible for processing the refresh_token grant. It receives two arguments:
- A context object with validated parameters and available helper functions.
- The original HTTP request, allowing deeper inspection if needed.
The context includes:
-
grantType:"refresh_token" -
clientId: Client ID associated with the request -
refreshToken: The received refresh token -
ttl: Access token TTL (as defined viasetTokenTTL) -
tokenType: Typically"Bearer" -
Optional:
clientSecret,scope -
Helpers:
createJwtAccessToken()– if JWT access token support is enabledcreateIdToken()– ifopenidis in scope and ID token support is activeverifyJwt()– available if the provider uses JWKS-based token verification
The handler must return:
- An
OAuth2TokenResponseinstance, or - An error object using
OAuth2ErrorCode, or nullto return a genericinvalid_requesterror.
✅ Example: Authorization Code Flow
import {
NoneAuthMethod,
OAuth2ErrorCode,
OAuth2TokenResponse,
OIDCAuthorizationCodeBuilder
} from '@kaapi/oauth2-auth-design';
export default OIDCAuthorizationCodeBuilder
.create()
.setTokenTTL(3600)
.addClientAuthenticationMethod(new NoneAuthMethod())
.useAccessTokenJwks(true)
.setScopes({
openid: 'User identity',
email: 'Access to user email',
})
.refreshTokenRoute(route =>
route
.setPath('/oauth2/token')
.generateToken(async ({
grantType,
clientId,
refreshToken,
ttl,
tokenType,
clientSecret,
scope,
createJwtAccessToken,
createIdToken,
verifyJwt
}, request) => {
// Example: Validate the refresh token and client
const isValid = true; // Replace with actual logic
if (!isValid) {
return {
error: OAuth2ErrorCode.INVALID_GRANT,
error_description: 'Invalid or expired refresh token'
};
}
return new OAuth2TokenResponse({ access_token: 'generated-access-token' })
.setExpiresIn(ttl)
.setTokenType(tokenType)
.setScope('openid email')
.setRefreshToken('new-optional-refresh-token')
.setIdToken('optional-id-token');
})
);
🧾 Handler Notes
- Use
verifyJwt()to validate JWT-based refresh tokens if they were originally created withcreateJwtAccessToken(). - If issuing a new refresh token (rotation), include it via
.setRefreshToken(). - If
openidis part of the requested scope, andcreateIdToken()is available, include a new ID token. - A refresh request may include a new or narrower
scope; validate this if necessary.
🧾 Return Types
✅ Successful Response
return new OAuth2TokenResponse({ access_token: '...' })
.setExpiresIn(ttl)
.setTokenType(tokenType)
.setScope('openid email')
.setRefreshToken('...')
.setIdToken('...');
❌ Specific Error
return {
error: OAuth2ErrorCode.INVALID_CLIENT,
error_description: 'Invalid client credentials'
};
❌ Generic Error
return null; // Returns "invalid_request"
📌 Note on Device Authorization Flow
The refreshTokenRoute() configuration is identical for the Device Authorization Flow.
You can reuse the same logic and structure shown above.
Refresh tokens are not available for the Client Credentials Flow and therefore refreshTokenRoute() is not supported in that context.
📌 Summary
refreshTokenRoute()defines how your server handles refresh token grants.- Only applicable for flows that issue refresh tokens (Authorization Code, Device Authorization).
- Offers full control over how refresh tokens are verified and how new tokens are issued.
- Works in tandem with
tokenRoute()and shares the same endpoint path by default (/oauth2/token).