Vai al contenuto
Torna alla documentazione di Launch

Scarica MarkdownDocumento originale su GitHub

Guida all'integrazione manuale (9 linguaggi, senza necessità di IA)

Questa guida si applica al fornitore Licentivo. I commercianti che dispongono di altri sistemi di autorizzazione possono selezionare un servizio personalizzato in «Selezione e personalizzazione dell'autorizzazione» nel backend, seguire le API di autorizzazione personalizzata e la procedura di integrazione e continuare a usare l'SDK del proprio sistema di autorizzazione.

Le modifiche attualmente non pubblicate adottano lo scambio dell'identità dell'account. Le responsabilità specifiche e i vincoli di migrazione sono descritti in Durata degli acquisti e limiti degli SDK account. Launch calcola la durata dell'acquisto; gli SDK Licentivo applicano l'autorizzazione.

Installare soltanto il pacchetto di integrazione Launch per il linguaggio corrispondente. Il pacchetto Launch include l'SDK ufficiale, l'adattatore predefinito e la configurazione della connessione; l'indirizzo ufficiale di autorizzazione è fisso: https://www.licentivo.com. Il programma accede usando l'account registrato dall'acquirente nel negozio Launch corrente.

Ottenere il codice di inizializzazione precompilato

  1. Completare nel backend Launch l'associazione tra software, piani di vendita e politiche di autorizzazione Licentivo, quindi pubblicarla nell'ambiente corrispondente.
  2. Aprire Integrazione del programma → Verifica dell'integrazione e codice, quindi selezionare software, linguaggio e ambiente di test/produzione.
  3. Fare clic su «Leggi le informazioni del prodotto e genera il codice di integrazione». Launch legge automaticamente l'indirizzo pubblico corrente del sito, le mappature dei prodotti esistenti e la chiave pubblica di firma.
  4. Copiare la funzione di connessione mostrata nella pagina nel proprio progetto e scrivere manualmente l'interfaccia e le chiamate applicative come descritto di seguito. È anche possibile esaminare i parametri compilati automaticamente e chiamare direttamente Connect/connect nel linguaggio corrispondente.

Non occorre inserire manualmente i due ID interni dei prodotti né generare launch-config.json o product.json. La pagina consente di salvare la funzione di connessione come codice sorgente. Il file privato del server config.yaml serve solo all'avvio del servizio Launch e non può essere distribuito con il software destinato ai clienti.

L'indirizzo del sito proviene dall'indirizzo pubblico valido dell'istanza corrente (public_url nella configurazione di avvio oppure l'indirizzo pubblico valido nelle impostazioni del sito nel backend). Può essere un nome di dominio o un indirizzo IP con porta, ma deve includere il protocollo; l'integrazione in produzione usa HTTPS valido. L'indirizzo di ascolto http_addr non è l'indirizzo di accesso dei clienti. Dopo aver cambiato l'indirizzo del sito, le mappature dei prodotti o l'ambiente, ottenere nuovamente la funzione di connessione dal sito corrente; le sessioni e le cache del vecchio sito non devono essere usate come autorizzazione per il nuovo sito.

I due identificativi dei prodotti rappresentano una corrispondenza interna già esistente: il prodotto software Launch e il prodotto di autorizzazione Licentivo. La pagina di integrazione li compila automaticamente in base al software selezionato; l'acquirente inserisce soltanto il proprio account del negozio. Il server legge la chiave pubblica di firma tramite la connessione Licentivo configurata; la chiave amministrativa e le credenziali di autorizzazione dei clienti non vengono incluse nel codice sorgente.

Funzione di Connect/connect

Connect/connect è il nome usato nei diversi linguaggi per l'operazione «crea un client applicativo Launch». Go, C# e alcune interfacce native usano Connect con iniziale maiuscola; Python, JavaScript, Ruby e altri linguaggi usano connect secondo le proprie convenzioni. connectLaunch(), connect_launch() o LaunchConnection.Open(), generati dal backend, sono funzioni del progetto con i parametri pubblici precompilati che chiamano internamente il punto di ingresso del linguaggio corrispondente.

La connessione completa soltanto l'inizializzazione: verifica l'indirizzo del negozio, le mappature dei prodotti, l'ambiente e la chiave pubblica di firma, crea il client Launch e configura l'SDK ufficiale Licentivo incluso nel pacchetto. Non verifica l'identità del cliente e non abilita direttamente le funzionalità a pagamento. La sequenza completa è:

Connect/connect → Login or Restore → RunFeature → Logout / Close
                                       └──────────→ ReleaseDevice (explicit device unlink only)

Durante l'esecuzione dell'applicazione, mantenere lo stesso oggetto client per consentire all'SDK di gestire correttamente gli heartbeat e i posti delle licenze flottanti. La chiusura ordinaria conserva l'associazione del dispositivo; la disconnessione esplicita del cliente e il punto di ingresso compatibile ReleaseDevice chiamano la stessa procedura di disconnessione dell'SDK ufficiale.

Installazione e punto di ingresso per l'inizializzazione

Tutte le verifiche dell'installazione pubblica nei nove linguaggi della versione 0.1.6 sono state superate (9/9); tutti i metodi di installazione della tabella seguente sono stati verificati. La release su GitHub fornisce anche pacchetti nativi e file offline; per l'uso, consultare le istruzioni di installazione dei pacchetti scaricati.

Lingua Installare solo Launch Funzione di connessione fornita dalla pagina API di inizializzazione diretta inclusa nel pacchetto
Go go get github.com/spf86/licentivo-launch-sdk/pkg/launchclient@v0.1.6 connectLaunch() launchclient.Connect
Python 3.10+ python -m pip install licentivo-launch==0.1.6 connect_launch() Application.connect
C# / .NET 8+ dotnet add package Licentivo.Launch --version 0.1.6 LaunchConnection.Open() Application.Connect
Java 17+ Maven/Gradle: com.licentivo.launch:launch-client:0.1.6 LaunchConnection.open() Launch.connect
Node.js 20.3+ npm install @licentivo/launch@0.1.6 connectLaunch() Application.connect
Rust 1.85+ cargo add licentivo-launch@=0.1.6 connect_launch() Application::connect
Ruby 3.1+ gem install licentivo-launch --version 0.1.6 connect_launch Application.connect
C11 Scaricare il pacchetto nativo dalla release su GitHub e importarlo con CMake connect_launch() launch_application_connect
C++17 Usare lo stesso pacchetto nativo Launch connectLaunch() Application::Connect

Il codice sorgente pubblico e i README dei singoli linguaggi sono disponibili nel repository degli SDK Launch, i pacchetti nativi e i file offline nella release v0.1.6 e i risultati delle installazioni pubbliche nella verifica dei registri per i nove linguaggi. Il README di ogni pacchetto fornisce i comandi di installazione e le API. Il pacchetto JavaScript include le dichiarazioni TypeScript. Le dipendenze ordinarie dei linguaggi vengono risolte dal gestore di pacchetti, ad esempio cryptography per Python, BouncyCastle per C# e base64 per Ruby; non occorre installare il pacchetto dell'SDK ufficiale.

Il modulo pubblico Go si chiama github.com/spf86/licentivo-launch-sdk e il percorso di importazione è github.com/spf86/licentivo-launch-sdk/pkg/launchclient; l'applicazione non richiede un replace locale. Il pacchetto nativo Windows usa amd64 GNU/MinGW; è disponibile anche un pacchetto nativo Linux amd64. I pacchetti Ruby specifici per piattaforma e la distribuzione Windows Rust/native includono curl; la compilazione dal sorgente su altre piattaforme richiede le normali dipendenze di sviluppo C11 e curl/OpenSSL. Le istruzioni sulle toolchain delle piattaforme si trovano nel README di ciascun pacchetto.

Accesso e operazioni protette

I frammenti seguenti usano la funzione di connessione copiata nel passaggio precedente. email e password provengono dalla propria interfaccia di accesso; le password non devono essere scritte nel codice sorgente o nella configurazione. export deve essere sostituito con il nome di una funzionalità effettivamente presente nella politica del piano.

Go

app, err := connectLaunch()
if err != nil { return err }
defer app.Close()
if _, err := app.Login(ctx, email, password); err != nil { return err }
return app.RunFeature("export", func() error {
    return exportReport()
})

ctx usa il contesto del ciclo di vita dell'applicazione: gli heartbeat non devono essere annullati subito al termine della richiesta di accesso. Eseguire le operazioni di rete in un thread di lavoro in background. Per il ripristino chiamare Restore(ctx); per disconnettere l'account chiamare Logout(ctx); per rilasciare il dispositivo chiamare ReleaseDevice(ctx).

Python

with connect_launch() as app:
    app.login(email, password)
    result = app.run_feature("export", export_report)

restore() ripristina una sessione sicura esistente; se non esiste una sessione, mostrare l'interfaccia di accesso. logout() elimina i dati dell'account; release_device() rilascia esplicitamente il dispositivo. Le operazioni di rete sincrone non devono bloccare il ciclo degli eventi dell'applicazione desktop.

C# / .NET

await using var app = LaunchConnection.Open();
await app.Login(email, password);
await app.RunFeature("export", async () => {
    await ExportReport();
});

Usare await Restore(), await Logout() e await ReleaseDevice(). Mantenere attivo il ciclo di vita dell'SDK per tutta la durata dell'applicazione e usare flussi di interfaccia asincroni.

Java

try (var app = LaunchConnection.open()) {
    app.login(email, passwordChars);
    app.runFeature("export", () -> exportReport());
}

La password usa char[]. Se non esiste una sessione, restore() restituisce un errore NO_SESSION e occorre mostrare l'interfaccia di accesso; gli altri errori non devono essere considerati un'autorizzazione. logout() e releaseDevice() sono operazioni distinte. La chiusura è gestita da try-with-resources.

JavaScript / Node.js / TypeScript

const app = connectLaunch();
try {
  await app.login(email, password);
  const result = await app.runFeature('export', () => exportReport());
} finally {
  await app.close();
}

restore() restituisce null quando non esiste una sessione; le operazioni applicative sono consentite solo dopo un ripristino riuscito. Il valore booleano restituito da logout() indica se la disconnessione remota è stata confermata; se il rilascio del dispositivo fallisce, occorre mostrare un errore. Il codice viene eseguito in Node.js, nel processo principale di Electron o in un backend attendibile; il browser e il processo di rendering di Electron non conservano credenziali di autorizzazione.

Rust

let mut app = connect_launch()?;
app.login(&email, &password)?;
let result = app.run_feature("export", || {
    export_report()?;
    Ok(())
})?;
app.close();

Il callback restituisce Result<T, Failure>. restore(), logout() e release_device() restituiscono risultati: gli errori devono essere gestiti. Anche Drop si occupa della chiusura del runtime. Per impostazione predefinita, il nucleo nativo viene compilato e collegato da build.rs; non occorre collegare manualmente l'SDK ufficiale.

Ruby

app = connect_launch
begin
  app.login(email, password)
  result = app.run_feature('export') { export_report }
ensure
  app.close
end

restore ripristina la sessione, logout disconnette l'account e release_device rilascia il dispositivo. Usare un blocco di codice per le operazioni protette; le eccezioni non devono essere convertite in esiti positivi.

C

static int export_action(void *context) {
    return export_report(context); /* Return 1 only on success. */
}

launch_application *app = connect_launch();
if (!app) return 0;
int ok = launch_application_login(app, email, password);
if (ok) ok = launch_application_run_feature(app, "export", export_action, context);
/* Check launch_application_error(app) on failure; never log credentials. */
launch_application_close(app);
return ok;

launch_application_restore prevede tre stati: 1 ripristino riuscito, 0 nessuna sessione, -1 errore. Solo l'assenza di una sessione deve portare alla normale visualizzazione dell'accesso; un rifiuto o un'eccezione non devono essere considerati un successo. È inoltre necessario verificare i valori restituiti da logout e release_device.

CMake importa soltanto Launch:

find_package(LicentivoLaunch CONFIG REQUIRED)
add_executable(myapp main.c)
licentivo_launch_link(myapp)

C++

auto app = connectLaunch();
app.Login(email.c_str(), password.c_str());
app.RunFeature("export", [&] { exportReport(); });

Restore(), Logout() e ReleaseDevice() seguono la semantica delle eccezioni C++. Il distruttore RAII gestisce la chiusura. CMake usa licentivo_launch_link(myapp CXX); Launch gestisce automaticamente il collegamento dell'SDK e le librerie runtime incluse nel pacchetto di distribuzione.

Ciclo di vita, archiviazione sicura ed errori

La creazione di un oggetto di connessione completa soltanto l'inizializzazione. Il programma deve aver effettuato l'accesso o ripristinato la sessione con successo e deve usare un callback di protezione della funzionalità per ogni operazione applicativa. Un ordine pagato, una sessione esistente o un pulsante cliccabile non sostituiscono la verifica dell'SDK.

Per impostazione predefinita, le sessioni vengono conservate soltanto in memoria. Per ricordare l'accesso occorre un'archiviazione sicura: Go, Python, C# e C/C++ nativi forniscono DPAPI per l'utente Windows corrente; Java, Node, Rust e Ruby forniscono un archivio AES-GCM che usa una chiave del chiamante. Le applicazioni multipiattaforma devono integrarsi con l'archivio delle credenziali del sistema. La chiave e il testo cifrato non devono essere collocati nella stessa normale directory.

La chiusura ordinaria conserva le sessioni che l'utente ha scelto esplicitamente di ricordare e arresta il runtime. La disconnessione dell'account chiama prima la procedura unificata di disconnessione dell'SDK ufficiale, quindi elimina i record dell'account propri di Launch. ReleaseDevice è un punto di ingresso compatibile della stessa procedura; se la revoca remota è ancora in sospeso, non si deve indicare che il rilascio è riuscito. Non eliminare la directory della cache dell'SDK ufficiale né i log di ripristino della disconnessione. La protezione delle sessioni di Launch non implica che tutti i file dei dispositivi dell'SDK ufficiale siano cifrati: occorre limitare i permessi della directory della cache.

Stato Gestione da parte del programma
Errore di account o password Mostrare un errore di accesso generico, senza rivelare se l'account esiste
EMAIL_VERIFICATION_REQUIRED Guidare l'utente nella verifica dell'indirizzo email del negozio
ENTITLEMENT_PENDING Mostrare la sincronizzazione in corso e attendere secondo i tentativi limitati del pacchetto e Retry-After
ENTITLEMENT_NOT_PURCHASED Guidare l'utente all'acquisto o al cambio di account
ENTITLEMENT_EXPIRED Guidare l'utente al rinnovo; non usare vecchie credenziali per aggirare il rifiuto
ENTITLEMENT_SUSPENDED Arrestare le funzionalità protette e contattare il commerciante
Limite di dispositivi raggiunto Guidare l'utente alla gestione o al rilascio esplicito dei dispositivi
Rete/HTTP 5xx È possibile usare soltanto autorizzazioni offline verificate dall'SDK e ancora valide

Risposte esplicite 401/403/404, account non corrispondenti, annullamenti o limiti di frequenza non devono essere trasformati in autorizzazioni offline riuscite. La prima attivazione e le politiche che vietano l'uso offline richiedono comunque una connessione di rete. Se il dominio/IP del server non è raggiungibile, mostrare un problema di connessione; non connettersi ad altri siti senza avviso.

Collaudo e riferimenti

Verificare l'accesso reale, l'autorizzazione appartenente all'account, le operazioni protette, il ripristino dopo il riavvio, l'autorizzazione offline valida e la sua scadenza, la manomissione della cache, la disconnessione, il cambio di account e il rilascio del dispositivo. Questo documento non richiede l'uso dell'IA. Per gli strumenti di test e i limiti del collaudo esterno, consultare acceptance.md; per i pacchetti locali e le istruzioni di compilazione, consultare integration-packages.md.

La verifica della configurazione, la generazione del codice e i test locali non dimostrano automaticamente che un pagamento reale, il rilascio di un'autorizzazione o l'attivazione sul sito ufficiale siano riusciti. I negozi esterni e le sandbox di pagamento devono essere configurati e collaudati separatamente.