API Reference¶
OAuth Endpoints¶
Authorization Endpoint¶
Initiates the authorization code flow.
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
response_type |
Yes | Must be code |
client_id |
Yes | OAuth app client ID |
redirect_uri |
Yes | Registered redirect URI |
scope |
Yes | Space-separated scopes |
state |
Recommended | CSRF protection token |
code_challenge |
Public clients | PKCE challenge |
code_challenge_method |
With challenge | Must be S256 |
nonce |
OIDC | OpenID Connect nonce |
Success Response: Redirect to redirect_uri with code and state
Error Response: Redirect with error and error_description
Token Endpoint¶
Exchange authorization code or credentials for tokens.
Authorization Code Grant¶
grant_type=authorization_code
code=<authorization_code>
redirect_uri=<registered_uri>
client_id=<client_id>
code_verifier=<pkce_verifier>
Client Credentials Grant¶
grant_type=client_credentials
client_id=<client_id>
client_secret=<client_secret>
scope=<requested_scopes>
Refresh Token Grant¶
Success Response:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "dGhp...",
"scope": "openid profile"
}
Error Response:
Introspection Endpoint¶
Validate and get information about a token.
POST /oauth/introspect
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
token=<access_token>
token_type_hint=access_token
Active Token Response:
{
"active": true,
"scope": "openid profile",
"client_id": "my-app",
"username": "user@example.com",
"token_type": "Bearer",
"exp": 1704067200,
"iat": 1704066300,
"sub": "550e8400-e29b-41d4-a716-446655440000",
"aud": ["my-app"]
}
Inactive Token Response:
Revocation Endpoint¶
Revoke an access or refresh token.
POST /oauth/revoke
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
token=<token>
token_type_hint=refresh_token
Response: Always returns 200 OK
Well-Known Endpoints¶
OpenID Configuration¶
Response:
{
"issuer": "https://api.example.com",
"authorization_endpoint": "https://api.example.com/oauth/authorize",
"token_endpoint": "https://api.example.com/oauth/token",
"introspection_endpoint": "https://api.example.com/oauth/introspect",
"revocation_endpoint": "https://api.example.com/oauth/revoke",
"jwks_uri": "https://api.example.com/.well-known/jwks.json",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token", "client_credentials"],
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "none"],
"code_challenge_methods_supported": ["S256"]
}
JSON Web Key Set¶
Response:
{
"keys": [
{
"kty": "RSA",
"kid": "key-id",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}
Go API¶
OAuth Provider¶
import "github.com/grokify/coreforge/identity/oauth"
// Create provider
cfg := oauth.DefaultConfig("https://api.example.com", []byte("secret"))
provider, err := oauth.NewProvider(entClient, cfg)
// Get Fosite provider
fosite := provider.OAuth2Provider()
// Get storage
storage := provider.Storage()
// Create session
session := provider.Session("user-id")
OAuth API¶
// Create API with Huma/Chi router
api, err := oauth.NewAPI(provider)
// Mount the router - all endpoints are automatically registered:
// - /oauth/authorize (GET/POST)
// - /oauth/token (POST)
// - /oauth/introspect (POST)
// - /oauth/revoke (POST)
// - /.well-known/openid-configuration (GET)
// - /.well-known/jwks.json (GET)
http.Handle("/", api.Router())
// Middleware for protected routes
protected := api.Middleware(myHandler)
Context Helpers¶
import "github.com/grokify/coreforge/identity/oauth"
// In handler after middleware
func myHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get user ID
userID := oauth.UserIDFromContext(ctx)
// Get scopes
scopes := oauth.ScopesFromContext(ctx)
// Check scope
if oauth.HasScope(ctx, "admin") {
// Has admin scope
}
// Get full access request
ar := oauth.AccessRequestFromContext(ctx)
}
Error Codes¶
| Code | Description |
|---|---|
invalid_request |
Malformed request |
invalid_client |
Client authentication failed |
invalid_grant |
Invalid authorization code or refresh token |
unauthorized_client |
Client not authorized for grant type |
unsupported_grant_type |
Grant type not supported |
invalid_scope |
Requested scope is invalid |
access_denied |
User denied authorization |
server_error |
Internal server error |