4601af88b5
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
46 lines
2.0 KiB
Markdown
46 lines
2.0 KiB
Markdown
---
|
|
name: oauth2_auth_url
|
|
kind: function
|
|
lang: go
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: pure
|
|
signature: "func Oauth2AuthURL(config OAuthConfig, state string) string"
|
|
description: "Construye la URL de autorizacion OAuth2 a partir de la config. Funcion pura que concatena el AuthURL del proveedor con los query params (client_id, redirect_uri, response_type=code, scope, state)."
|
|
tags: [oauth, oauth2, auth, url, infra]
|
|
uses_functions: []
|
|
uses_types: [OAuthConfig_go_infra]
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: ""
|
|
imports: [net/url, strings]
|
|
params:
|
|
- name: config
|
|
desc: "OAuthConfig del proveedor (Google, GitHub, etc.) con ClientID, AuthURL, RedirectURL y Scopes"
|
|
- name: state
|
|
desc: "valor aleatorio anti-CSRF que debe validarse en el callback. Si es vacio no se añade"
|
|
output: "URL completa a la que redirigir al usuario para iniciar el flujo OAuth2"
|
|
tested: true
|
|
tests: ["genera URL con todos los params basicos", "concatena scopes con espacio", "añade state si no es vacio", "detecta si AuthURL ya trae query y usa & en vez de ?"]
|
|
test_file_path: "functions/infra/oauth2_auth_url_test.go"
|
|
file_path: "functions/infra/oauth2_auth_url.go"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```go
|
|
google := OAuthConfig{
|
|
ClientID: os.Getenv("GOOGLE_CLIENT_ID"),
|
|
AuthURL: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
RedirectURL: "http://localhost:8080/callback",
|
|
Scopes: []string{"openid", "email", "profile"},
|
|
}
|
|
state := "random-anti-csrf-token" // guardar en cookie/session
|
|
url := Oauth2AuthURL(google, state)
|
|
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
|
|
```
|
|
|
|
## Notas
|
|
|
|
Pura — solo hace string building con `net/url.Values.Encode()` (ordena params alfabeticamente y hace URL-encoding). No lee env, ni toca I/O, ni `time.Now()`. El state es critico para prevenir CSRF: debe ser aleatorio por sesion, guardarse server-side (cookie firmada, session, etc.) y validarse en el callback antes de hacer Oauth2Exchange. Un state vacio significa sin proteccion CSRF y no se incluye en la URL — solo apto para pruebas locales.
|