Pular para o conteúdo principal

Get started

This page takes you from an API key to a signed hash: install a client, create a session, send the user to a provider, and use the session that comes back. Each step has code in C#, PHP, Python, Node.js and Java. How it works explains the flow behind the steps.

The code signs a hash that your signature library computed. Signing a PDF and Authentication show complete handlers that compute that hash and finish the signature with PKI SDK, Rest PKI or PKI Express.

1. Get an API key​

Ask Lacuna Software support (suporte@lacunasoftware.com) for a CloudHub API key, and list the redirect URIs your application will use, for production and for development. If you will add your own parameters to the redirect URI, as the examples below do with fileId, ask for a host entry such as https://app.example.com instead of an exact URI. See Redirect URIs.

The examples read the key from the CLOUDHUB_API_KEY environment variable. Keep it on the server.

2. Install a client​

dotnet add package Lacuna.Cloudhub.Client

For ASP.NET Core dependency injection, add Lacuna.Cloudhub.ClientCore as well.

3. Create a client​

using Lacuna.Cloudhub.Api;
using Lacuna.Cloudhub.Client;

var cloudhub = new CloudhubClient(
"https://cloudhub.lacunasoftware.com/",
Environment.GetEnvironmentVariable("CLOUDHUB_API_KEY"));

With Lacuna.Cloudhub.ClientCore, register the client once and inject ICloudhubService, which has the same methods:

Program.cs
using Lacuna.Cloudhub.ClientCore;

builder.Services.AddCloudhub().Configure(builder.Configuration.GetSection("Cloudhub"));
appsettings.json
{
"Cloudhub": {
"Endpoint": "https://cloudhub.lacunasoftware.com/",
"ApiKey": "set it in user secrets or an environment variable"
}
}

4. Create a session​

Send the signer's CPF, digits only, and the URI CloudHub should send the user back to. The examples carry the ID of the file to sign in the redirect URI, so that the request that comes back knows which file it is for.

var session = await cloudhub.CreateSessionAsync(new SessionCreateRequest {
Identifier = "12345678909",
RedirectUri = "https://app.example.com/sign/complete?fileId=42",
Type = TrustServiceSessionTypes.SingleSignature,
LifetimeInSeconds = 300,
});

foreach (var service in session.Services) {
Console.WriteLine($"{service.ServiceInfo.Provider}: {service.AuthUrl}");
}

An empty list means that no provider holds a certificate for that CPF. Tell the user, and offer to try another CPF.

5. Send the user to a provider​

Render one choice per entry and navigate the browser to the authUrl the user picks. badgeUrl is the provider's logo and may be null.

<!-- One link per entry of "services" -->
<a href="https://api.birdid.com.br/oauth/authorize?client_id=…">
<img src="https://cdn.lacunasoftware.com/img/psc/birdid.png" alt="BirdID" height="48">
Sign with SOLUTI
</a>

The user signs in at the provider and approves. The provider sends the browser back to CloudHub, and CloudHub sends it to your redirect URI.

6. Read the certificate when the user comes back​

Your redirect URI receives the session parameter beside your own. When session is missing, the user did not authorize: send them back to choose again.

// ASP.NET Core: GET /sign/complete?fileId=42&session=…
public async Task<IActionResult> Complete(string fileId, string session) {
if (string.IsNullOrEmpty(session)) {
return RedirectToAction("Index", new { fileId });
}

byte[] certificate = await cloudhub.GetCertificateAsync(session);
// ...
}

Before you sign, check that the certificate belongs to the person you expected: compare the CPF in it with the one you sent. The complete examples do this with their signature library.

7. Sign a hash​

Your signature library gives you the hash to sign and its digest algorithm. Send both with the session; the result is the signature value, for your library to embed in the document. Identify the algorithm by OID (digestAlgorithmOid), as the signature libraries report it, or by name (digestAlgorithm, such as SHA-256).

byte[] signature = await cloudhub.SignHashAsync(new SignHashRequest {
Session = session,
Hash = toSignHash, // the hash, as bytes
DigestAlgorithmOid = digestAlgorithmOid,
});

8. Handle errors​

CloudHub reports a problem with your request as HTTP 422 and a JSON body with a code, a message and sometimes details. The code you will meet most is SessionExpired: the session ran out before you used it, so send the user through the provider again. The REST API page lists every code.

try {
var signature = await cloudhub.SignHashAsync(request);
} catch (CloudhubApiException ex) when (ex.CodeStr == "SessionExpired") {
// Create a new session and send the user to the provider again
}

Compare CodeStr. The Code enum property is not filled in from the response.

A request without a valid API key gets HTTP 401. An unexpected failure, such as a provider that is down, gets HTTP 500 with a short code in the body; quote it when you contact support.

Next steps​

  • Signing a PDF: the complete PAdES flow, with the signature library computing the hash and finishing the PDF.
  • Authentication: sign users in with their cloud certificate.
  • How it works: SignatureSession for signing several documents with one authorization.
View as Markdown