Skip to main content

Vanilla Code

Is this the right authentication method for you?

Before starting to read this page, we invite you to check if this is the best authentication method for you. Please check the flowchart you can find on the Authentication page before proceeding.

The OAuth 2.0 Authentication Code Flow is the recommended method to retrieve an Access Token for applications that have access to secure, private storage such as web applications deployed on a server; if your use case isn't compatible with this requirement, we suggest checking the Authentication page to check the other methods supported by our app.

This is not a general explanation

This guide describes our implementation of the OAuth 2.0 Authentication Code flow. If you are interested in a more general explanation of this concept, please refer to the dedicated page.

To interact with our API on behalf of the user using this flow, it is necessary to implement the steps explained below.

Code Examples

In this guide, we'll try to keep our code examples as vanilla as possible, but we also added specific OAuth helpers to our SDKs to make the authorization implementation painless. If possible, we strongly suggest to use them.

Additionally, some open-source OAuth 2.0 libraries are available for each programming language. Those libraries take care of some of the following steps for you, so feel free to choose the one that you prefer to help you with the OAuth implementation.

In the last section of this page, you can find a non-exhaustive list of the available frameworks for each of the programming languages, but some others may be available.

🔑  Token types

Here's a quick reminder of the three tokens that we'll obtain in the following steps. All of the three tokens are pseudo casual strings with a specific prefix that can be used to discern each one of the tokens; each one of the tokens has a specific purpose and a lifespan (e.g. an expiration time) that define their validity.

Token NameDescriptionPrefixLifespan
Authorization CodeThis is the token you will exchange to get an Access Token. It is valid only one time and has a very short lifespan.c/60 seconds (from its emission)
Access TokenThis is the token you will use to make requests.a/24 hours (from its emission)
Refresh TokenThis is the token you will use only to make refresh requests to obtain a new Access Token when the old one expires, without having to ask the user to give a new explicit authorization. When it expires it is necessary to perform this flow again from step 1.r/1 year (from the last refresh request)

0️⃣  Prerequisites: Create an app and retrieve the credentials

The Authentication Code flow requires specific credentials, that are specific to a single application. You can create an app following this guide: Create an app.

While creating the app, you need to select the OAuth 2.0 authentication and authorization method and retrieve the Client ID and Client Secret credentials: you will need them in the following steps.

Never share the Client Secret!!!

The Client Secret, used in the OAuth 2.0 flow, is a piece of sensible information so it must NEVER be shared with third-party actors, and it must always be kept safe (for example in an environment variable used by your backend). Never share it with other people, or publish it on your frontend! If it happened, then we suggest you to delete your application on the Fatture in Cloud page.

On the same page, you need to define a Redirect URL: it is an endpoint that must be exposed by your application to be able to receive the Authorization Code.

For this chapter, we will use the https://www.yourapplication.com/redirect URL, but you are free to specify one that best fits your needs.

note

The Redirect URI must be formally valid, and it will be checked while creating the application. For local development purposes, also the localhost URI is enabled (for example, you can declare "http://localhost:8080" to reach your backend running locally).

1️⃣  Redirect the user to the Fatture in Cloud authorization page

An external application can consume our API resources only if the owner gives permission to do it. The permissions can be obtained on a dedicated page published by Fatture in Cloud.

To perform this step, you just need to redirect the user to a specific URL; this URL will contain some specific information that must be collected beforehand:

Parameter nameDescription
response_typeMust be set to "code". This indicates that you are requesting an authorization code.
client_idYour Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see the previous step).
redirect_uriThe URL to which you want to redirect the user after completing the authorization process. Note that this must be the same that you provided while creating the app.
scopeA space-separated list of permissions you are asking for your app. See the Scopes page for further information.
stateA custom, request-specific string parameter generated by your application, that can be double-checked in the next step (see the following note).
The state parameter

The state parameter is intended to preserve some state object set by the client in the Authorization request, and make it available to the client in the response. The main security reason for this is to stop Cross Site Request Forgery (XSRF). XSRF attacks are not new or specific to OAuth, and the way to prevent them is to include something in the request that the client can verify in the response but that an attacker could not know. An example of this would be a hash of the session cookie or a random value stored in the server linked to the session. If the client can’t verify the value returned, then it must reject authentication responses that could be generated as the result of requests by third-party attackers. Also, if you need to keep any other pieces of information you can encode it in the state parameter as well since it is just a string.

Below you can see some vanilla code examples that will help you build the URL for the redirect.

var baseUrl = "https://api-v2.fattureincloud.it";
var authorizePath = "/oauth/authorize";

var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var scopes = "scope:r scope:a"; // space separed list of scopes

var state = "EXAMPLE_STATE"; // a state generated by your application for this specific request

var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query.Add("response_type", "code");
query.Add("client_id", clientId);
query.Add("redirect_uri", redirectUrl);
query.Add("scope", scopes);
query.Add("state", state);

var authorizeUrl = baseUrl + authorizePath + '?' + query; // the url to be used

The generated URL, with URL-encoded params, will look like this:

https://api-v2.fattureincloud.it/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fwww.yourapplication.com%2Fredirect&scope=scope%3Ar%20scope%3Aa&state=EXAMPLE_STATE
You must redirect!

This is not a simple HTTP GET request, you need to be able to open a browser page to complete this step.

Once the URL is generated, you must use it to redirect the user. Once landed on the Fatture in Cloud page, the user will be required to:

  • Login to Fatture in Cloud using his account credentials;
  • Give explicit consent to the permissions requested by the application. These operations will be performed automatically by our page, so you don't need to worry about them.
Scopes and permissions

Please note that the permissions requested to the user on our page will be strictly related to the scopes you picked and inserted in the query string.

It is important to select the minimum set of scopes required by your application to fulfill your use case: if you select too few, you may obtain some 403 Forbidden errors while performing operations out of the scope set, while if you select too many the user could feel overwhelmed and reject your permissions request entirely.

2️⃣  Obtain the Authorization Code

Once the user gave explicit consent to your request, our page will redirect the user to the Redirect URL specified in the previous step (in the example, to https://www.yourapplication.com/redirect).

Our page will share two parameters with your application:

Parameter nameDescription
stateThe state string, as provided in the previous step.
codeThe Authorization Code token.

The two parameters will be sent to your application as URL-encoded query string parameters, so your application must be able to manage appropriately the following HTTP GET request (in this example, we use "AUTH_CODE" as value for the returned Authorization Code):

GET https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54

Most frameworks take care of extracting the query string params for you. In case you need to extract the params from the URL on your own, you can use the following code:

// in this example we define the var url as string, but it should come from the HTTP request
var url = new Uri("https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54");

var state = System.Web.HttpUtility.ParseQueryString(url.Query).Get("state");
var code = System.Web.HttpUtility.ParseQueryString(url.Query).Get("code");

Once you extracted the two parameters, you must check the state parameter value; if it doesn’t match, then probably a third party created the request, and you should abort the process.

If the state is valid, then you can use the code parameter to perform the next step.

3️⃣  Obtain the Access Token

The Authorization Code obtained above has only one purpose: to exchange it with an Access Token.

Once you checked that the state is valid, you can use it to retrieve the token with a POST HTTP call to the https://api-v2.fattureincloud.it/oauth/token endpoint.

The parameters required for the request are the following:

Parameter nameDescription
grant_typeMust be set to "authorization_code". This indicates that you want to exchange an Authorization Code for an Access Token.
client_idYour Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see the previous step).
client_secretYour Client Secret, e.g. the secret of your app. You can find it on your Fatture in Cloud application page (see the previous step).
redirect_uriThe same redirect URL defined previously.
codeThe Authorization Code obtained in the previous step.
Keep it secret!

It is important to keep the Client Secret a secret. So it must be stored carefully and it should be used only in backend applications. Don't commit it to public repositories and don't use it where the users could obtain it (for example in frontend applications).

Check the Redirect URI!!!

We perform a String Equals to compare the Redirect URI you will send in the following request and the one you inserted in the Application page, so they must be exactly the same. This means that if the two paths are equivalent but the strings are different (for example, because you added a "/" at the end of only one of the two strings) you will still obtain an error.

Also, if you use different applications for your different environments (for example, DEV and PROD), please use the correct Redirect URI for the environment you're currently in: if the two redirect URIs are different and you're using the DEV redirect URI while running in PROD env, you'll obtain an error.

The cURL command will look like this:

curl --request POST \
--url https://api-v2.fattureincloud.it/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "authorization_code",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"redirect_uri": "https://www.yourapplication.com/redirect",
"code": "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54"
}
'

Below you can find some vanilla code examples implementing the same command.

// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp

using System;
using RestSharp;

namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the code as string, but you should have obtained it in the previous steps
var code = "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";

var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";

var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret

var params = new {
grant_type = "authorization_code",
client_id = clientId,
client_secret = clientSecret,
redirect_uri = redirectUrl,
code = code
};

var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(params);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}

The response body will be similar to the following:

{
"token_type": "bearer",
"access_token": "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJTQzJLSlRpTjVXTTBORFR0SWd2Y1o4cmhFR1ZrdmFjRiIsImV4cCI6MTU4OTY0MDk3M30.DNG4jX8Au3WMxVtb06RUNi0Dj5cDylagpZPgDLhpIhY",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY",
"expires_in": 86400
}

The returned parameters are:

Parameter nameDescription
token_typeSet as "bearer", it indicates how to use the returned token in the following REST calls.
access_tokenThe Access Token.
refresh_tokenThe Refresh Token.
expires_inThe validity of the Access Token in seconds before its expiration.

As you can see, the REST call will return the Access Token and the Refresh Token. The Access Token can be used to perform multiple API requests, but it expires after a certain amount of time. The Refresh Token instead can be used to obtain a new Access Token once the previous one is expired; it also expires, but its lifespan is higher than the Access Token one.

We're done!

Now you can use the Access Token to interact with the Fatture in Cloud API. In the next section, you'll see how to use it to perform a request.

Protect the tokens!!!

The Access Token (and by extension the Refresh Token) makes it possible to perform operations on the Fatture in Cloud API on behalf of the user, thus your application will be able to read and modify the user's own resources. This means that the tokens are a precious resource that must be protected (avoid sending them to the frontend).

Also, your application will obtain a dedicated token set for each one of the users, so it will be necessary to correctly associate a single user to his own tokens.

📃  Complete Helper

Here you can find all the code from the previous paragraphs put togheter in a single class.

using RestSharp;
using System;

namespace OauthQuickstart.Helpers
{
public class FattureInCloudOauth2Provider
{
//============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the
* credentials provided at the creation of your FattureInCloud app.
*/

// Replace with your redirect url (ex. http://localhost:5000/)
static string redirectUrl = "REDIRECT_URL";
// Replace with your client Id
static string clientId = "CLIENT_ID";
// Replace with your client Secret
static string clientSecret = "CLIENT_SECRET";
// Replace with the required scopes
static string scopes = "entity.suppliers:a";
//============================================================================================================================================

// The following properties and methods are needed for the oauth token management
// No need to edit anything
static string baseUrl = "https://api-v2.fattureincloud.it";
static string authorizePath = "/oauth/authorize";
static string tokenPath = "/oauth/token";

public static string GetAuthorizationUrl(string state)
{
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query.Add("response_type", "code");
query.Add("client_id", clientId);
query.Add("redirect_uri", redirectUrl);
query.Add("scope", scopes);
query.Add("state", state);

string url = baseUrl + authorizePath + '?' + query; // the url to be used
return url;
}

public static string getAccessTokenUrl()
{
return baseUrl + tokenPath;
}

public static string getAccessToken(string code)
{
Object obj = new
{
grant_type = "authorization_code",
client_id = clientId,
client_secret = clientSecret,
redirect_uri = redirectUrl,
code = code
};

var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(obj);
IRestResponse response = client.Execute(request);

return(response.Content.ToString());
}
}
}

💼  Find your Company ID

Even if this step is not strictly part of the Authentication process, it is required to be able to use the Company-scoped Methods. Once you obtain the Access Token, you can use the List User Companies method to retrieve the ID of the related Company; please check the Company-scoped Methods page for further info.

  Perform an API request

A valid Access Token can be used to authorize requests included in the scopes authorized by the user at step one; to obtain a valid response it is necessary to include the Access Token in your request as an HTTP header.

In the following example, we'll simulate a Get Supplier call. We choose this method because it is relatively easy to understand and it requires the entity.suppliers:r scope to be authorized correctly.

Please, notice that for the purposes of this example we will assume that we already know the parameters required by the request and that we have previously acquired a valid Access Token performing the steps above.

curl --request GET \
--url https://api-v2.fattureincloud.it/c/17/entities/suppliers/16 \
--header 'Accept: application/json'
--header 'Authorization: Bearer a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4'

The corresponding code is the following:

// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp

using System;
using RestSharp;

namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the token as string, but you should have obtained it in the previous steps
// the token is valid for the "received_documents:r" scope needed to perform this operation
var token = "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4";

// these parameters are usually retrieved through our APIs or stored in a DB
var companyId = 16;
var supplierId = 17;

var url = "https://api-v2.fattureincloud.it/c/" + companyId + "/entities/suppliers/" + supplierId,;

var client = new RestClient(url);
var request = new RestRequest(Method.GET);

request.AddHeader("authorization", "Bearer " + token);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}

If the Access Token is valid and provided correctly in the header, the response will be a 200 OK. To check the possible error responses, please check the dedicated page.

♻️  Refreshing the token

When the Access Token expires, you have two options to keep performing authenticated requests:

  • Obtain a new one performing steps 1-3
  • Obtain a new one using the Refresh Token

Please, note that the first option once again requires user interaction, so we suggest performing it again only when the Refresh Token is expired.

Similar to what happens in step 3, you can obtain a new token with a POST HTTP call to the https://api-v2.fattureincloud.it/oauth/token endpoint.

The parameters required for the request are the following:

Parameter nameDescription
grant_typeMust be set to "refresh_token". This indicates that you want to exchange a Refresh Token for an Access Token.
client_idYour Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see above).
client_secretYour Client Secret, e.g. the secret of your app. You can find it on your Fatture in Cloud application page (see above).
refresh_tokenThe Refresh Token obtained previously.

The cURL command will look like this:

curl --request POST \
--url https://api-v2.fattureincloud.it/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "refresh_token",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY"
}
'

Below you can find some vanilla code examples:

// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp

using System;
using RestSharp;

namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the code as string, but you should have obtained it in the previous steps
var refreshToken = "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO542";

var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";

var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret

var params = new {
grant_type = "refresh_token",
client_id = clientId,
client_secret = clientSecret,
refreshToken = refreshToken
};

var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer " + token);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(params);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}

The response body will be similar to the following:

{
"token_type": "bearer",
"access_token": "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJRUWVwVUgxOFJwY05oN0hoR0g4Rmsxd3BnZUFOSHBBMiJ9.dkStK6xIY-wgjwdQZZF5rrjH_tfLr4BB4dfGB7zuLO8",
"expires_in": 86400
}

The returned parameters are:

Parameter nameDescription
token_typeSet as "bearer", it indicates how to use the returned token in the following REST calls.
access_tokenThe Access Token.
refresh_tokenThe Refresh Token.
expires_inThe validity of the Access Token in seconds before its expiration.

The obtained token can be used exactly as explained in step 3 of this guide.

📝  Change Token permissions

Unfortunately, if you need to change the set of permissions that you are currently requiring from your app users, you can't do it by preserving the old token: you must discard the old token on your code and replace it with a new one obtained after updating the scopes list at Step 1.

📚  OAuth 2.0 libraries

Here you can find a useful non-exhaustive list of OAuth 2.0 Client libraries for different programming languages. You can use them to take care of some of the tedious tasks in this guide for you, such as the composition of the redirect URL or the retrieval of the Access Token. Feel free to choose the one that best fits your needs.