1e5dfa5193
Fase 4 del issue 0010 — cliente OAuth2 sin golang.org/x/oauth2. - Oauth2AuthURL es pura: solo construye la URL con net/url - Oauth2Exchange/Refresh hacen POST application/x-www-form-urlencoded - ExpiresAt calculado como now + expires_in del proveedor - Refresh conserva el token original si el proveedor no devuelve uno nuevo - Tests con httptest.NewServer como mock del proveedor
2.1 KiB
2.1 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| oauth2_exchange | function | go | infra | 1.0.0 | impure | func Oauth2Exchange(config OAuthConfig, code string) (OAuthTokens, error) | Intercambia un authorization code por tokens OAuth2. POST al TokenURL del proveedor con grant_type=authorization_code y las credenciales del cliente. Retorna OAuthTokens con AccessToken, RefreshToken y ExpiresAt calculado. |
|
|
|
false | error_go_core |
|
|
OAuthTokens con access/refresh tokens. ExpiresAt = now + expires_in del proveedor | true |
|
functions/infra/oauth2_exchange_test.go | functions/infra/oauth2_exchange.go |
Ejemplo
code := r.URL.Query().Get("code")
state := r.URL.Query().Get("state")
// Validar state contra el guardado en cookie/session...
tokens, err := Oauth2Exchange(googleConfig, code)
if err != nil {
HTTPErrorResponse(w, HTTPError{Status: 500, Code: "oauth_error", Message: err.Error()})
return
}
// Usar tokens.AccessToken para llamar a APIs del proveedor
Notas
Impura — hace POST HTTP al TokenURL con timeout de 30s, y usa time.Now() para calcular ExpiresAt. El body es application/x-www-form-urlencoded (estandar OAuth2). Si el proveedor retorna JSON con campo error se wrappea en un error descriptivo. El ClientSecret se envia en el body (no en header Authorization Basic) para compatibilidad amplia — la mayoria de proveedores aceptan ambos. NO valida el state anti-CSRF: eso debe hacerlo el handler del callback antes de llamar a Oauth2Exchange.