--- name: http_session_token_extract kind: function lang: go domain: infra version: "1.0.0" purity: pure signature: "func SessionTokenExtract(r *http.Request, cookieName string) string" description: "Extrae el token de sesion de un request HTTP. Comprueba primero la cookie con el nombre indicado; si no esta, parsea el header Authorization 'Bearer '. Retorna cadena vacia si no hay token." tags: [http, session, cookie, bearer, auth, token] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "" imports: ["net/http"] params: - name: r desc: "request HTTP entrante" - name: cookieName desc: "nombre de la cookie de sesion a buscar (p.ej. 'kanban_session')" output: "token extraido de la cookie o del header Authorization; cadena vacia si no hay token en ninguna fuente" tested: true tests: - "cookie present retorna token de cookie" - "bearer header retorna token de header" - "cookie gana sobre bearer header" - "sin token retorna cadena vacia" test_file_path: "functions/infra/http_session_token_extract_test.go" file_path: "functions/infra/http_session_token_extract.go" --- ## Ejemplo ```go func authMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := infra.SessionTokenExtract(r, "my_session") if token == "" { http.Error(w, "unauthorized", http.StatusUnauthorized) return } // validate token... next.ServeHTTP(w, r) }) } ``` ## Notas Extraido de apps/kanban/backend/auth.go. Funcion pura: solo lee el request, no muta estado. La cookie tiene precedencia sobre el header Authorization para mantener consistencia con el comportamiento del browser (la cookie es el canal primario; el header es para clientes API que no gestionan cookies).