mirror of
https://github.com/click33/sa-token-go.git
synced 2025-12-24 13:48:04 +08:00
English | 中文文档
OAuth2 Authorization Code Flow Example
Complete OAuth2 authorization code flow implementation example.
Features
- Authorization Code Grant - Standard OAuth2 authorization code flow
- Token Refresh - Refresh access tokens using refresh tokens
- Token Validation - Validate access tokens
- Token Revocation - Revoke access tokens
- Multiple Clients - Support for multiple OAuth2 clients
- Scope Management - Fine-grained permission control
Quick Start
1. Run the Server
cd examples/oauth2-example
go run main.go
Server runs on http://localhost:8080
2. OAuth2 Flow
Step 1: Authorization Request
curl "http://localhost:8080/oauth/authorize?client_id=webapp&redirect_uri=http://localhost:8080/callback&response_type=code&state=xyz123"
Response:
{
"message": "Authorization code generated",
"code": "a3f5d8b2c1e4f6a9...",
"redirect_url": "http://localhost:8080/callback?code=...&state=xyz123",
"user_id": "user123",
"scopes": ["read", "write"]
}
Step 2: Exchange Code for Token
curl -X POST http://localhost:8080/oauth/token \
-d "grant_type=authorization_code" \
-d "code=a3f5d8b2c1e4f6a9..." \
-d "client_id=webapp" \
-d "client_secret=secret123" \
-d "redirect_uri=http://localhost:8080/callback"
Response:
{
"access_token": "b4f6d9c3d2e5f7b0...",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "c5f7e0d4e3f6e8c1...",
"scope": ["read", "write"]
}
Step 3: Use Access Token
curl http://localhost:8080/oauth/userinfo \
-H "Authorization: Bearer b4f6d9c3d2e5f7b0..."
Response:
{
"user_id": "user123",
"client_id": "webapp",
"scopes": ["read", "write"],
"expires_in": 7200,
"issued_at": 1700000000
}
Step 4: Refresh Access Token
curl -X POST http://localhost:8080/oauth/token \
-d "grant_type=refresh_token" \
-d "refresh_token=c5f7e0d4e3f6e8c1..." \
-d "client_id=webapp" \
-d "client_secret=secret123"
Step 5: Revoke Token
curl -X POST http://localhost:8080/oauth/revoke \
-d "token=b4f6d9c3d2e5f7b0..."
Registered Clients
Web Application
Client ID: webapp
Client Secret: secret123
Redirect URIs:
- http://localhost:8080/callback
- http://localhost:3000/callback
Scopes: read, write, profile
Mobile Application
Client ID: mobile-app
Client Secret: mobile-secret-456
Redirect URIs:
- myapp://oauth/callback
Scopes: read, write
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/oauth/authorize |
GET | Authorization endpoint |
/oauth/token |
POST | Token endpoint |
/oauth/userinfo |
GET | User info endpoint |
/oauth/revoke |
POST | Token revocation endpoint |
Authorization Request Parameters
| Parameter | Required | Description |
|---|---|---|
client_id |
Yes | Client identifier |
redirect_uri |
Yes | Callback URI |
response_type |
Yes | Must be "code" |
state |
Recommended | CSRF protection |
scope |
Optional | Requested scopes |
Token Request Parameters
Authorization Code Grant
| Parameter | Required | Description |
|---|---|---|
grant_type |
Yes | "authorization_code" |
code |
Yes | Authorization code |
client_id |
Yes | Client identifier |
client_secret |
Yes | Client secret |
redirect_uri |
Yes | Must match authorization request |
Refresh Token Grant
| Parameter | Required | Description |
|---|---|---|
grant_type |
Yes | "refresh_token" |
refresh_token |
Yes | Refresh token |
client_id |
Yes | Client identifier |
client_secret |
Yes | Client secret |
Security Features
- Client Authentication - Client secret verification
- Redirect URI Validation - Prevent open redirect attacks
- State Parameter - CSRF protection
- Code Expiration - Authorization codes expire in 10 minutes
- Token Expiration - Access tokens expire in 2 hours
- One-time Use - Authorization codes can only be used once
- Scope Validation - Requested scopes must be allowed
Integration Example
package main
import (
"github.com/click33/sa-token-go/core"
"github.com/click33/sa-token-go/storage/memory"
)
func main() {
storage := memory.NewStorage()
oauth2Server := core.NewOAuth2Server(storage)
// Register client
oauth2Server.RegisterClient(&core.OAuth2Client{
ClientID: "my-app",
ClientSecret: "my-secret",
RedirectURIs: []string{"http://localhost:3000/callback"},
GrantTypes: []core.OAuth2GrantType{core.GrantTypeAuthorizationCode},
Scopes: []string{"read", "write"},
})
// Generate authorization code
authCode, _ := oauth2Server.GenerateAuthorizationCode(
"my-app",
"http://localhost:3000/callback",
"user123",
[]string{"read"},
)
// Exchange code for token
token, _ := oauth2Server.ExchangeCodeForToken(
authCode.Code,
"my-app",
"my-secret",
"http://localhost:3000/callback",
)
// Validate token
validated, _ := oauth2Server.ValidateAccessToken(token.Token)
// Refresh token
newToken, _ := oauth2Server.RefreshAccessToken(
token.RefreshToken,
"my-app",
"my-secret",
)
}