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
- Completare nel backend Launch l'associazione tra software, piani di vendita e politiche di autorizzazione Licentivo, quindi pubblicarla nell'ambiente corrispondente.
- Aprire Integrazione del programma → Verifica dell'integrazione e codice, quindi selezionare software, linguaggio e ambiente di test/produzione.
- 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.
- 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/connectnel 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.