-
Notifications
You must be signed in to change notification settings - Fork 567
feat(oauth2): add /oauth/token endpoint
#2159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Pull Request Test Coverage Report for Build 17646441416Details
💛 - Coveralls |
/token endpoint/oauth/token endpoint
cstockton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing jumps out at me, but I did see this in the handler.go that is a bit confusing to me. Given ClientSecret is not initialized I think it's essentially a NOOP. I think I understand the flow of the client secret, but can we remove the code / comment below to make it more clear?
func oauthServerClientToResponse(client *models.OAuthServerClient, includeSecret bool) *OAuthServerClientResponse {
// cstockton: ClientSecret is not set here
response := &OAuthServerClientResponse{
ClientID: client.ID.String(),
ClientType: client.ClientType,
// OAuth 2.1 DCR fields
RedirectURIs: client.GetRedirectURIs(),
TokenEndpointAuthMethod: tokenEndpointAuthMethods,
GrantTypes: client.GetGrantTypes(),
ResponseTypes: []string{"code"}, // Always "code" in OAuth 2.1
ClientName: utilities.StringValue(client.ClientName),
ClientURI: utilities.StringValue(client.ClientURI),
LogoURI: utilities.StringValue(client.LogoURI),
// Metadata fields
RegistrationType: client.RegistrationType,
CreatedAt: client.CreatedAt,
UpdatedAt: client.UpdatedAt,
}
// Only include client_secret during registration and only for confidential clients
if includeSecret && client.IsConfidential() {
// cstockton: So I don't entirely understand this, but would like to:
// Note: This will be filled in by the handler with the plaintext secret
response.ClientSecret = ""
}
Good catch, yeah this part is unnecessary. I added this part before implementing #2152, so we don't need anymore, removed the |
migrations/20250904133000_add_oauth_client_id_to_session.up.sql
Outdated
Show resolved
Hide resolved
hf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please consider the index!
🤖 I have created a release *beep* *boop* --- ## [2.180.0](v2.179.0...v2.180.0) (2025-09-23) ### Features * add OAuth client type ([#2152](#2152)) ([b118f1f](b118f1f)) * add phone to sms webhook payload ([#2160](#2160)) ([d475ac1](d475ac1)) * background template reloading p1 - baseline decomposition ([#2148](#2148)) ([746c937](746c937)) * config reloading with fsnotify, poller fallback, and signals ([#2161](#2161)) ([c77d512](c77d512)) * enhance issuer URL validation in OAuth server metadata ([#2164](#2164)) ([a9424d2](a9424d2)) * implement OAuth2 authorization endpoint ([#2107](#2107)) ([5318552](5318552)) * **oauth2:** add `/oauth/token` endpoint ([#2159](#2159)) ([a89a0b0](a89a0b0)) * **oauth2:** add admin endpoint to regenerate OAuth client secrets ([#2170](#2170)) ([0bd1c28](0bd1c28)) * **oauth2:** return redirect_uri on GET authorization ([#2175](#2175)) ([b0a0c3e](b0a0c3e)) * **oauth2:** use `id` field as the public client_id ([#2154](#2154)) ([86b7de4](86b7de4)) * **openapi:** add OAuth 2.1 server endpoints and clarify OAuth modes ([#2165](#2165)) ([1f804a2](1f804a2)) * password changed email notification ([#2176](#2176)) ([fe0fd04](fe0fd04)) * support `transfer_sub` in apple id tokens ([#2162](#2162)) ([8a71006](8a71006)) ### Bug Fixes * ensure request context exists in API db operations ([#2171](#2171)) ([060a992](060a992)) * **makefile:** remove invalid @ symbol from shell commands ([#2168](#2168)) ([e6afe45](e6afe45)) * **oauth2:** switch to Origin header for request validation ([#2174](#2174)) ([42bc9ab](42bc9ab)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## Summary This PR completes the OAuth2 server implementation by adding the `/token` endpoint, enabling full OAuth2 authorization code flow & refresh token support. ## Key Features Added: ### OAuth Token Endpoint (POST /oauth/token) supporting: - `authorization_code` grant type for exchanging authorization codes for access - refresh_token grant type for token refresh - Both JSON and form-encoded request bodies - OAuth Client authentication via Basic auth or request body parameters (form params and JSON body) ### Token Service Integration: - Integrated OAuth server with the existing token service - Added OAuth-specific authentication method (`oauth_provider/authorization_code`) - Enhanced token generation to include OAuth client context in JWT claims. ## Database Changes: - Added `oauth_client_id` field to `sessions` table for OAuth client tracking. So an OAuth clients can use a refresh token only if the session is issued for them. Similarly, a session issued to a client can only be refreshed by that client (i.e user can't use `/token?grant_type=refresh_token` endpoint with a refresh token obtained through `/oauth/token` endpoint.) ## Next Steps - Adding ratelimit for the `/token` endpoint - Store token auth method for oauth clients in the database
🤖 I have created a release *beep* *boop* --- ## [2.180.0](v2.179.0...v2.180.0) (2025-09-23) ### Features * add OAuth client type ([#2152](#2152)) ([b118f1f](b118f1f)) * add phone to sms webhook payload ([#2160](#2160)) ([d475ac1](d475ac1)) * background template reloading p1 - baseline decomposition ([#2148](#2148)) ([746c937](746c937)) * config reloading with fsnotify, poller fallback, and signals ([#2161](#2161)) ([c77d512](c77d512)) * enhance issuer URL validation in OAuth server metadata ([#2164](#2164)) ([a9424d2](a9424d2)) * implement OAuth2 authorization endpoint ([#2107](#2107)) ([5318552](5318552)) * **oauth2:** add `/oauth/token` endpoint ([#2159](#2159)) ([a89a0b0](a89a0b0)) * **oauth2:** add admin endpoint to regenerate OAuth client secrets ([#2170](#2170)) ([0bd1c28](0bd1c28)) * **oauth2:** return redirect_uri on GET authorization ([#2175](#2175)) ([b0a0c3e](b0a0c3e)) * **oauth2:** use `id` field as the public client_id ([#2154](#2154)) ([86b7de4](86b7de4)) * **openapi:** add OAuth 2.1 server endpoints and clarify OAuth modes ([#2165](#2165)) ([1f804a2](1f804a2)) * password changed email notification ([#2176](#2176)) ([fe0fd04](fe0fd04)) * support `transfer_sub` in apple id tokens ([#2162](#2162)) ([8a71006](8a71006)) ### Bug Fixes * ensure request context exists in API db operations ([#2171](#2171)) ([060a992](060a992)) * **makefile:** remove invalid @ symbol from shell commands ([#2168](#2168)) ([e6afe45](e6afe45)) * **oauth2:** switch to Origin header for request validation ([#2174](#2174)) ([42bc9ab](42bc9ab)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
This PR completes the OAuth2 server implementation by adding the
/tokenendpoint, enabling full OAuth2 authorization code flow & refresh token support.Key Features Added:
OAuth Token Endpoint (POST /oauth/token) supporting:
authorization_codegrant type for exchanging authorization codes for accessToken Service Integration:
oauth_provider/authorization_code)Database Changes:
oauth_client_idfield tosessionstable for OAuth client tracking. So an OAuth clients can use a refresh token only if the session is issued for them. Similarly, a session issued to a client can only be refreshed by that client (i.e user can't use/token?grant_type=refresh_tokenendpoint with a refresh token obtained through/oauth/tokenendpoint.)Next Steps
/tokenendpoint