OAuth

OAuth

Prerequisites

Before you start coding an OAuth implementation for your integration, you need to make a few decisions and preparations:

  • Decide whether you need code or password authentication.
  • Have available the client id and secret provided when you registered with the Act-On Developer community.
  • If you'd like to use any java code samples we provide for trying out our APIs (including the one at the end of this topic), first download the java unirest library from unirest.io.

Password or code authentication?

  • For integrations that you develop in-house, where you have direct access to user account credentials, we recommend password authentication.
  • For integrations that you develop as a third party, where you can't store user credentials within the application, and/or where you connect to several Act-On accounts, we recommend code authentication.

Even if you plan to use grant type code, an understanding of how grant type password works is useful.

Client id and secret

As a member of the Act-On developer community, you have a client id and secret that was sent to you when you registered (if you have problems finding them, go to https://developer.act-on.com/provision/). Use the client id and secret for all of your session access requests.

Session access and refresh requests

Your code needs to observe the basic OAuth 2.0 patterns for authentication and access as follows:

  • An initial session access request must contain the client ID and secret in addition to individual user credentials.
  • A response to a successful access request contains a session access token and a refresh token.
  • Each session access token counts down from 3600 seconds.
  • To continue using Act-On after a session access token expires, you must send a request that contains a refresh token with no prior use.
  • Each refresh token can only be used once and lasts until another refresh grant is issued for the same Act-On user/client ID pair.

Grant Type Password

POST requests for grant type password to the the token endpoint:

https://restapi.actonsoftware.com/token

using the following properties:

name value
grant_type password
username {Act-On user (email address)}
password {Act-On user password}
client_id {client_id}
client_secret {client_secret}

Example HTTP request

NOTE: replace the placeholder text in brackets with your client id and password.

POST /token HTTP/1.1
Host: restapi.actonsoftware.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=<your_email>%40.com&password=<your_pwd>&client_id=<your_clientid>&client_secret=<
your_client_secret

Example curl requests

NOTE: replace the placeholder text in brackets with your client id and password.

curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=password&username=%40url.com&password=welcome2here&client_id=<your_clientid>&client_secret=your_client_secret' https://restapi.actonsoftware.com/token

Example response when using grant_type password :

 {
 "token_type":"bearer",
 "expires_in":3600,
 "refresh_token":"6d84dba1e8b55d795983af10abffffff"
 ,"access_token":"ec96c219f477cb695644498ffffff"
 }
oauth_pwd

Grant type code

With grant_type code, the end user's valid login request causes a redirect to a page that requests an authorization from them. When they respond by clicking Yes, your application should then forward valid credentials:

GET https://restapi.actonsoftware.com/authorize?scope=PRODUCTION&response_type=code&client_id={{client_id}}&state={{optional}}
The response containing the grant code is sent to your redirect URL.
The default setting for the redirect is https://localhost. If you have not yet re-configured this please email us at [email protected] for a new URL.
The "state" parameter is optional and will be returned as passed by the request to your callback URL. This allows for session tracking.
A response will look like the following:
https://localhost/?code=db5b2d1d7c569c6ef8166267ffffff

POST the code from the above response to the token endpoint to obtain session access and refresh tokens:

https://restapi.actonsoftware.com/token
Name Value Notes
code {grant_code} Returned to your callback URL from the previous request
client_id {client_id}
client_secret {client_secret}
redirect_uri {your_redirect URI}
grant_type authorization_code

Example HTTP request

NOTE: replace the placeholder text in brackets with your code, client ID and client secret.

POST /token HTTP/1.1
Host: restapi.actonsoftware.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=<CODE>&client_id=<CLIENT ID>&client_secret=<CLIENT SECRET>&redirect_uri=<REDIRECT URI>

Example curl request

Following is a sample curl request.

NOTE: replace the placeholder text in brackets with your code, client ID and client secret.

curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=<CODE>&client_id=<CLIENT ID>&client_secret=<CLIENT SECRET>&redirect_uri=<REDIRECT URI>' https://restapi.actonsoftware.com/token

The response is just like the response for password grant type:

{
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"6d84dba1e8b55d795983af10abffffff"
,"access_token":"ec96c219f477cb695644498ffffff"
}

Your code needs to:

  • Store the returned access token for the purpose of authenticating subsequent non-authorization requests until the token expires. (3600 seconds)
  • Store the returned refresh token for the purpose of getting a new access token after the access token expires.
  • Use the access token for all non-authentication related requests as specified by documentation for endpoints you are using. Access tokens expire in 3600 seconds.
  • To refresh a session, use the refresh token from the immediate prior session in a refresh request. When the refresh request is granted, the response contains another access token/refresh token pair.

The refresh token does not expire until a new initial access token request or a refresh request occurs.

Access token requests are limited to 5 per hour. Using this workflow avoids unneeded access token requests and prevents your application from reaching this limit.

Refresh request

POST to the token endpoint:

 https://restapi.actonsoftware.com/token
name value
refresh_token {saved refresh token}
grant_type refresh_token
client_id {client_id}
client_secret {client_secret}

Example HTTP request

NOTE: replace the placeholder text in brackets with your refresh token, client ID and client secret.

POST /token HTTP/1.1
Host: restapi.actonsoftware.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=<REFRESH TOKEN>&client_id=<CLIENT ID>&client_secret=<CLIENT SECRET>

Example curl request

NOTE: replace the placeholder text in brackets with your refresh token, client ID and client secret.

	curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=refresh_token&refresh_token=<REFRESH TOKEN>&client_id=<CLIENT ID>&client_secret=<CLIENT SECRET>' https://restapi.actonsoftware.com/token

An example response from a grant_type of refresh_token is:

{
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"6d84dba1e8b55d795983af10abffffff"
,"access_token":"ec96c219f477cb695644498ffffff"
}

Using refresh tokens to continue sessions allows you to avoid re-issue of password or code grant type request, which are limited to 5 per hour.

Code Examples

These examples use the java unirest library available at unirest.io. You can also find unirest libraries for node, ruby, php, java, objective c, python, and .net.

Java

package com.acton.api.client.endpoint;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;

public class ListExample 
	{

	static String BASE_URL 			= "https://restapi.actonsoftware.com/";
	static String ACTON_USERNAME 	= "";
	static String ACTON_PASSWORD 	= "";
	static String CLIENT_ID 		= "";
	static String CLIENT_SECRET 	= "";

	public static void main(String[] args) 
		{
		try	{
			String access_token = getAccessToken();
			Unirest.setDefaultHeader("Authorization", "Bearer " + access_token);
			printListCount();
			}

		catch (UnirestException e) {
			e.printStackTrace();
        	}
    	}

	/*
	 * This method uses GET list api, to print the total number of lists.
	 */

	private static void printListCount() throws UnirestException 
		{
        HttpResponse listResponse = Unirest.get(BASE_URL + "/api/1/list").asJson();
        System.out.println("Total number of lists : " + listResponse.getBody().getObject().getInt("totalCount"));
    	}

	/*
	 * This is a utility method to get an access token
	 */

	private static String getAccessToken() throws UnirestException 
		{
        //POST to token url with password grant_type to get token.

		HttpResponse jsonResponse = Unirest.post(BASE_URL + "token")
			.header("accept", "application/json")
			.field("grant_type", "password")
			.field("username", ACTON_USERNAME)
			.field("password", ACTON_PASSWORD)
			.field("client_id", CLIENT_ID)
			.field("client_secret", CLIENT_SECRET)
			.asJson();

		//Strip access_token from response and return it.

		return jsonResponse.getBody().getObject().getString("access_token");
		}
	}