Linx Main Linx Help

OAuth 2.0 authentication [GitHub example]


The OAuth 2.0 Authorization Framework enables third-party applications such as a Linx Solution to obtain access to protected resources (i.e account details, documents etc) from a host (i.e. Microsoft, Facebook, GitHub etc. ) with permission from a resource owner (user). This is achieved by orchestrating an approval interaction between the resource owner, the host and the third-party application.

The authorization action by the resource owner (user) typically happens only once and following that there is a cycle of client-to-server re-authorization that ‘refresh’ the application’s authentication credentials.

The advantage of using the OAuth 2.0 flow is that a resource owner’s personal credentials (i.e. password and username) are never shared and the resource owner does not have to pre-configure anything on their side, only action the authorization when requested.

In order to implement the OAuth 2.0 - Authorization Code Grant flow in Linx, a combination of hosting and consuming REST web services will be used. This will allow resources owners to authorize your application to access their resources without any manual intervention.

The below sections are covered in this guide:

Need help?

For personal support queries, please contact or reply on this article.

Authorization Code Grant flow

The below diagram illustrates the OAuth 2.0 - Authorization Code Grant:


  • (A): The flow is initiated by the resource owner (user) triggering the flow from the user-agent (browser) - this is done by the user browsing to a URL which will execute a request against a Linx API (client).

    The API will respond with an authorization URL and will direct the resource owner’s
    user-agent (browser) to the authorization endpoint.

    The client includes its client identifier, requested scope, local state, and a redirection URI to which the authorization server will send the user-agent back once access is granted (or denied).

  • (B): The resource owner then authorizes (or denies) the client’s access request via the user-agent (broswer).

  • (C): The authorization server redirects the user-agent back to the client using the
    redirection URI provided earlier (in the request or during client registration).

    The Redirect URL will be a Linx API endpoint which will then receive the below details.

    The redirection URI includes an authorization code and any local state provided by the client

  • (D): The client requests an access token from the authorization server’s token endpoint by including the authorization code received in the previous step. When making the request, the client authenticates with the authorization server. The client includes the redirection URI used to obtain the authorization code for verification.

  • (E): The authorization server authenticates the client, validates the authorization code, and ensures that the redirection URI received matches the URI used to redirect the client in step (C). If valid, the authorization server responds back with an access token and, optionally, a refresh token.

Building a basic generic authenticator with Linx

In the following sections we will be covering how to build an automated authenticator that will allow you to connect to any API via OAuth 2.0.

The resulting user flow will look like the below:


A sample Solution has been provided below to aid understanding and provide a "basic" template for implementing the OAuth 2.0 flow in Linx.

GenericOAuth2Authenticator.lsoz (26.3 KB)

Registering your application

In this tutorial, I will be using the example of connecting to GitHub.

Before connecting to your target API, you need to gather the below details:

  • Client credentials: The Client ID and Client Secret (sometimes referred to as App ID/App Secret). These are obtained by registering an application on the provider’s website or developer portal.
  • Endpoint URIs: The Authorization and Token generation URIs should be available on the official documentation of the platform you are trying to connect to.
  • Redirection URI: The redirect URI or Callback URL is used to return the Access Token. This is set when registering the application and can be changed at a later stage.

In order to generate the above information, you need to register your App on the providers website/developer portal.


For GitHub, ensure you register an "OAuth application".

After you have registered your application, you should have:

  • Client ID
  • Client Secret
  • Redirect URI

Example of registering a new application (GitHub):

Application’s (client) identifiers (GitHub):

Important: Ensure you generate a client secret and store it somewhere for later:

Authorization Request


The Authorization Request involves the client (Linx) constructing a URI which points to the target host authorization endpoint. The resource owner (user) is directed to this URI following by the user-agent (web browser) , following this, he/she will authorize the application to have access to the protected resource (typically indicated by the scope parameter).

The Authorization URI is in the following format:

Name Description Example
{host} REQUIRED Host server
{authorize-endpoint} REQUIRED Authorization endpoint for Host server /login/oauth/authorize
{response_type} REQUIRED Value must be set to code code
{client_id} REQUIRED Client identifier generated on target system application registration 8527f38c3c4a0d8726fa
{scope} OPTIONAL Optional list of access scopes , depending on the host repo, user
{state} RECOMMENDED Random string of characters used to verify the response from the server and prevent cross-site forgery QjKc
{redirect_uri} OPTIONAL Redirect URI where the server will send a request to containing the authorization code after a successful authorization http://localhost:8080/oauth/token

The built up URI will be similar to the below:, user&state=QjKc&redirect_uri=http://localhost:8080/oauth/token

Try it yourself by manually creating the Authorization URI with your client credentials.

The Authorization URI will need to be browsed to every time you want to re-initiate the token generation flow. You can save this URI somewhere for quick reference, however, during development you’ll most likely need to remove and re-add apps, and therefore generate new client identifiers. In order to make life easier in such cases we are going to get Linx to build up the Authorization URI for us.

This will be a Process that takes in a number of client credentials that we generated in the previous step.

The process will return a single output which will contain that input values, built up using string manipulations. This way, whenever the client identifiers change, we can update a single value in our Linx Solution and regenerate the Authorization URI.

To create a generic process that will generate and return the Authorization URI:

  1. Create a new Solution.

  2. Add a Process and rename it to GenerateAuthorizationUri.

  3. Configure the GenerateAuthorizationUri process to have the below $.Input values:

    • host
    • authorize_endpoint
    • response_type
    • client_id
    • scope
    • state
    • redirect_uri

    When adding $.Inputs , you can set the default values for debugging by setting the Value to the default for that input.


  4. Configure the GenerateAuthorizationUri process to have a single $.Output with the Name of uri.

  5. Add a SetValueFNC to the process.

    This will be used to build up a string combining the inputs into the proper format.

  6. For the Target, reference $.Output.uri.

  7. For the Source, use an expression to build up the query values of the uri along with the input client credentials:

    =$ + $.Input.authorize_endpoint + "?" + "response_type=" + $.Input.response_type + "&client_id="+$.Input.client_id+"&scope="+$.Input.scope+"&state="+$.Input.state+"&redirect_uri=" + $.Input.redirect_uri
  8. Debug the GenerateAuthorizationUri process.

  9. When the process completes, take a look at the Debug Values panel and take note of the $.Output.uri value.


  10. Copy the uri and paste it in your web browser.

  11. You should be promoted to authorize your application:

  12. Once you’ve granted access, your user-agent (browser) should redirect you to the Redirect URI that you set earlier, i.e. http://localhost:8080/oauth/token.

  13. The URL will contain 2 query parameters:

    • code: Authorization code returned from Authorization Server to use for generating tokens.
    • state: Random string to link flow requests.


For the next section we will be using the value of the code parameter. The state parameter will be touched on later.

Exchange Authorization Code for an Access Token


After the Authorization Response has been recieved, the code parameter can be exchanged with the host for an access token.

This typically involves making a POST request to the token issuing endpoint , with a Content-Type of URL encoded , submitting the identifiers below as the list of URL encoded content parameters.


If successful, a (200) OK response will be returned containing a JSON string containing access token related data in varying formats similiar to the below:


      "access_token": "EAAkXlZBnWqyEBAIaOnwmOph34B3y9ooVBSPiMB07ut7FQcHFAXDFkwo9UcVihyiZB4DhcFqjrtHam",

      "token_type": "bearer",

      "expires_in": 5178671


The value contained in the access_token field will then be submitted in the Authorization header with the value of Bearer {access_token}.

  1. Add a new Process and rename it ExchangeCodeForToken.

  2. Add the following $.Input parameters:

    • host
    • token_endpoint
    • client_id
    • client_secret
    • state
    • redirect_uri
    • code

    Configure the default values of these fields like before, you will need to generate a Client Secret if you haven’t done so already.


  3. Add a CallRESTEndpointFNC to the ExchangeCodeForToken process.

  4. Set the URL with an expression which will combine the input host and token_endpoint value:

    =$ + $.Input.token_endpoint
  5. Change the Method to POST.

  6. Set the Body format as URL Encoded Content.

  7. A URL encoded body field will appear:
    Expand the editor and add the parameters like below:

  8. Debug the ExchangeCodeForToken with the correct $.Input values (Copy the code paramter from the redirection URL and add it to the Solution).

    When the request is made, the variables will be encoded and submitted like below:

    POST HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 182
    Connection: Keep-Alive

    The authorization code is only valid for a certain period of time. If it has expired, you will need to re-initiate the flow by generating the Authorization URL again with the GenerateAuthorizationUri process.

    If the request was successful a response should be returned with a ResponseBody like below:


    This response is a single string value, which is not typical of token responses. Typically, access tokens are returned as application/json. With GitHub, you are able to specify the content type of the response object by adding an Accept header value.

  9. Add a Header to the request like below:

  10. Debug the ExchangeCodeForToken with the correct $.Input values.

  11. The Response Body should now still be a single string, but it is in JSON format like below:


    Use a JSON formatter to parse the text into fields to see the response.

Returning the access token

The current response is returned as a StringTYP . In order to parse the text into the respective fields, the response object needs to be imported as a CustomTYP.


See more about importing responses.

Once imported, the Output type can reference this structure and the fields will be parsed.

  1. Import the Response Body as a CustomTYP and give it the name token.

  2. You should have a tokenTYP like the below:

  3. Set the Output type of the CallRESTEndpoint in the ExchangeCodeForToken process.

  4. Add an $.Output to the ExchangeCodeForToken process with a Name of token and the Type of Project.Token.

    This will return the entire token object details which will allow us access to all the details when the ExchangeCodeForToken process is called.

  5. Add a SetValueFNC to the end of the ExchangeCodeForToken process.

  6. For the Target, reference $.Output.token.

  7. For Source, reference CallRESTEndpoint.ResponseBody.

  8. Debug the process again and take note of how the Response Body has been deserialized into the token object and the token returned as an output:


    Copy the the value of the ResponseBody.token.access_token and save it for the next section.

Using the access token

To demonstrate how access token’s are used in a request, the below steps outline how to add an Authorization header with the value of Bearer {token}.


Find out more about bearer authentication here

Extending the example of GitHub, a request is going to be made to the /user endpoint.

The token generated from the earlier step will be added to the Authorization header.

The response will contain information related to the authenticated user.

  1. Create a new Process and rename it GetAuthenticatedUser.

  2. Add an access_token $.Input parameter.

  3. Add a CallRESTEndpointFNC to the GetAuthenticatedUser process.

  4. Set the URL as

  5. Expand the Headers editor and add the header with a Name of Authorization.

  6. For the Value , use an expression like below:

    ="Bearer " + $.Input.access_token
  7. Debug the GetAuthenticatedUser process, copy and paste the access_token from the previous step into the $.Input.access_token.

    The request should fail with an output like below:

    Response code: 403 (Forbidden)
    Response Body:
    Request forbidden by administrative rules. Please make sure your request has a User-Agent header 

    This is a specific issue with the GitHub API, more details on the solution can be found here.

    To resolve the issue add the following as the User-Agent header:

    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 YaBrowser/ Yowser/2.5 Safari/537.36


  8. Debug the GetAuthenticatedUser process again, you should recieve a 200 (OK) like below:

    CallRESTEndpoint: URL Constructed
    CallRESTEndpoint: HTTP client created
    CallRESTEndpoint: Sending GET request
    CallRESTEndpoint: Request Headers:
    CallRESTEndpoint: Authorization = Bearer debb277f9a880460a14abd4cdd474d7406fc6724
    CallRESTEndpoint: User-Agent = Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 YaBrowser/ Yowser/2.5 Safari/537.36
    CallRESTEndpoint: Response received
    CallRESTEndpoint: -----------------
    CallRESTEndpoint: Response code: 200 (OK)
    CallRESTEndpoint: Response Body:
    "company":"yourusercompany ",
    "blog":" ",
    "bio":" ",
  9. Import the response as a CustomTYP and use it to return details from the GetAuthenticatedUser process. (This will be used later in the tutorial).

Well done, you’ve successfully implemented a Generic OAuth 2.0 Provider with Linx, however, in its current state, the application is basic and requires manual intervention.

Automating the whole flow

So far, we’ve created custom processes to successfully:

  • generate an authorization URL
  • make a request for an access token
  • use the access token in the request

However, it still requires manual intervention for the most part.

In order to automate the entire authentication flow as well as add in some nice to haves, we are going to do the following:

  • recieve a request to generate the authorization URI
  • generate an authorization URI
  • return and redirect user-agent to the authorization URI.
  • receive the redirection request containing the authorization code.
  • automatically make a request for an access token using the authorization code
  • use the access token in the request

The result will be the below:

Automatically re-direct users to the Authorization URI

Currently, you need to manually debug the GenerateAuthorizationUri process and copy out the URL and then browse to it.

To make life easier, we are going to create a REST operation that will receive a GET request. When the user browses to this hosted url, the operation is executed, it will then make a call to the GenerateAuthorizationUri process which will return a uri.


Get started with the RESTHost Tutorial here

In the response of the operation, the uri will be returned in the Location header along with an Status Code of 301 (Redirect). What this does is that when a request is made to the operation, the response redirects the user-agent (browser) to the authorization uri.

The advantage of this is that you can set up a static URL to navigate to (this can be a bookmark in your browser or a link on a page) - when you browse to this url, the current client identifiers will be used to generate the authorization uri.

  1. Add a RESTHostSVC to your Solution.

  2. Set the Base URI as http:localhost:8080

  3. Import the below API definition:

         openapi: 3.0.0
           version: '1'
           title: LinxOAuth2
           description: Linx web service to automate the Authentication Code Grant flow
               description: Generates authorization URL for user authentication.
               operationId: AuthorizeRequest
                   description: Redirect
                         type: string

    This will create a AuthorizeRequest operation in the Solution Explorer.


    When the AuthorizeRequest operation is called, it will execute the GenerateAuthorizationUri process and return the output of it.

  1. Drag the GenerateAuthorizationUri process from the Solution Explorer, onto the AuthorizeRequest operation selected in the canvas panel.

    You will notice the the local process call to the GenerateAuthorizationUri process has empty input parameters:


    The default values that were set only apply when debugging the Process and not when you make a process call to that Process.

    You could “hardcode” the inputs like below:

    However, client identifiers often change and going back into this operation to change them will cause issues.

    To resolve this, its generally best practice to store variables like this as a constant or :gear: $.Setting of the Solution and reference the $.Settings.value when needed:


    If you debug the AuthorizeRequest operation, you will see the GenerateAuthorizationUri process return a uri output containing the built up uri string.

  2. In order to return this uri in the response and redirect the user-agent to this address we first need to indicate in the response that this is a (301) Redirect which will make the user-agent navigate to the value provided in the Location header.

    To do this, the $.Output.Data.HttpContext.StatusCode needs to be set to 301.

    The Location header then needs to be added to the response which will contain the location of the redirect address which in this case will be the generated authorization uri.

    Add a SetValueFNC to the AuthorizeRequest operation and rename it SetValue_Response301.

  3. For the Target reference the whole $.Output.Data.HttpContext object.

  4. For the Source, expand the field editor.

  5. Set the StatusCode as 301.

  6. Expand the Headers editor and add a Location header which references the output of the GenerateAuthorizationUri process like below:

To test the above out, we are going to locally host the REST web service and use it to make requests against.

To host a REST web service locally:

  1. Right-click on the RESTHostSVC in the Solution Explorer.

  2. Click ⮞ Debug.

  3. Once the Debugger has initialized, click ⮞ Start

  4. In your browser, make a request to THIS URI.


    While developing, you will most likely make several repeating requests in your browser. As a result the browser may store a cache of some of the information which leads to errors during the flow. To resolve this, clear your cache or initiate the request in an incognito window.
  5. If successful, you should be redirect to the GitHub authorization page to login.

Each time you need re-generate an authorization code, just navigate to the /authorize url.


Bookmark the http://localhost:8080/oauth/authorize uri in your web browser to make testing easier.

Automatically request tokens after authorization.

Currently, when you authorize the application, you will be redirect to the redirect URI which would be:


Your browser will display a (404) Not Found error like below:


This is because there is no host listening on that address.

We are now going to add an ExchangeCode operation to our RESTHostSVC and host it on the redirection uri.

The operation will take in the code and state parameters as part of the query string.

The operation will then call the ExchangeCodeForToken process from earlier.

The code passed in with the URL would be passed into the ExchangeCodeForToken process to exchange with the Authorization Server.

Once the token has been generated, it will be passed into the GetAuthenticatedUser process.

A request would then be made using the token to return the currently authenticated user’s details.

These details will then be returned in the Response Body of the operation.

  1. Add the below path and parameters to the API definition:

               description: Generates Access Token
               operationId: ExchangeCode
                 - in: query
                   name: state
                     type: string
                 - in: query
                   name: code
                     type: string
                   description: ResponseXXX
                         type: string

    This will create an ExchangeCode operation in the Solution Explorer:


    The operation recieves 2 input parameters:

    The operation is configured to have a generic Response Body of a StringTYP .

  1. Drag the ExchangeCodeForToken process from the Solution Explorer onto the ExchangeCode operation.

  2. Configure the input values for ExchangeCodeForToken process call the like below:


    You will see how the code and state input values reference the $.Input.Data.code and $.Input.Data.state of the operation.

  3. Once the ExchangeCodeForToken process completes successfully, we will return a simple text message confirming the successful authentication.

    First the status code of the response must be set to indicate the result i.e. 200, 401, 403 etc.

    To do this, drag a SetValueFNC below the ExchangeCodeForToken process and rename it to SetValue_Response200.

  4. For the Target, reference $.Output.Data.HttpContext.

  5. Expand the Source and set the value of the Status Code field to 200.

    This indicates the request result was successful.

  6. For the Response Body, we are just going to return a simple text message.

    Add another SetValueFNC and rename it SetValue_ResponseBody.

    For the Target, reference $.Output.Data.ResponseXXX.

    For the Source, set it as the text “OAuth 2.0 flow success!”

  7. Debug the RESTHostSVC like below and navigate to the /authorize local endpoint from earlier:

    Now, after you authorize the application, the user-agent makes a request to the Redirect URI which is our ExchangeCode operation.

    The code and state parameters are parsed from the query string and then passed into the ExchangeCodeForToken process.

    Once completed, the operation returns a message to the user-agent.

Full flow (no step through):

Customizing the response

To personalize the response, we are going to use the GetAuthenticatedUser process to return details of the user that just granted access to the application. This is done purely to demonstrate using the access token when making a request.

  1. Drag the GetAuthenticatedUser process from the Solution Explorer, into the ExchangeCode operation, positioning it right below the ExchangeCodeForToken process.

  2. For the access_token input of GetAuthenticatedUser, reference the token generated from the ExchangeCodeForToken process like below:


  3. We now use the user details returned from the GetAuthenticatedUser process to personaize the response message.

    Alter the Source of the SetValue_ResponseBody like below:

    ="GitHub User '" + + "' successfully authenticated"

    Now, when the flow completes, a personal message is returned.

Storing and retrieving the access token

In its current state, the Solution successfully generates and uses the access token. However, to re-authorize and generate a new token each time a request is made is impractical. As Linx does not persist data unless stored as a setting, you will need to store the token in a datasource of some kind (database, text file), in order to retrieve for later use in requests.

To demonstrate the concept, we are going to create a generic process that will store the access token object in a local text file.


Typically, access tokens would be stored in a database, for the use in this demonstration we will use a file instead as some users may have not set up a database

We are then going to create a generic process that will return the token details when they are needed n a request.

Logging the token

  1. Create a new Process and rename it LogToken.

  2. For the $.Inputs, add a token field and reference the Project.token object as the Type.

  3. Within the LogToken process, add a TextFileWriteFNC .

  4. For the File path we are going to create a :gear: $.Setting value which will store the location of the file.

    We can then reference this value when reading and writing from the file.

  5. For the Contents. we want to store the whole token object as plain text.


    If you reference a whole CustomTYP object as a string input i.e. when writing the contents of a file, the custom type details will not be able to be converted into text implicitly. In order to explicitly convert a CustomTYP into text, you need to assign it to StringTYP first.

    To explicitly convert the token into text o use for storage, add a StringTYP instance to the process and rename it stringifyToken.

    For the Value, reference the whole $.Input.token. This will explicitly converted the custom type structure and values into a JSON string.

  6. For the Contents of the TextFileWrite, reference stringifyToken.

  7. Ensure the File exists is set to Overwrite.

    This means that if the file exits already, then the current contents of the file will be overwritten.

You are then able to make a process call to the LogToken process, in the ExchangeCode operation, passing in the token that was just generated (i.e. ExchangeCodeForToken.token):

Now, if you re-initiate the whole flow again, the token response object will be logged in the “token.txt” text file:

Retrieving the token

By storing the whole JSON string of the object, we are able to read the contents back out and assign them directly into our tokenTYP, this makes working with the individual fields easier.

We are now going to build a Process that will read the contents from “token.txt”, assign it to the tokenTYP and return the details. This Process can then be called from other processes when a request is made. The latest stored token will be returned and then can be used in the Authorization header.

  1. Create a new Process and rename it RetrieveToken.

  2. For the $.Outputs, add a token field and reference the Project.token object as the Type.

  3. Within the RetrieveToken process, add a TextFileReadFNC .

  4. For the File path, reference the same $.Settings value that was used when writing to the file (i.e. $.Settings.token_log_path).

  5. For the Return options, select Complete.

    This will read the entire contents fom the file as a single StringTYP .

  6. As the JSON stored in the file maps directly to the tokenTYP, we can use a SetValueFNC to assign the output of the TextFileRead directly to the $.Output.token of the RetrieveToken process.

You are then able to call RetrieveToken wherever you need the current access token to make a request.

To demonstrate:

  1. Remove the $.Input.access_token field for the GetAuthenticatedUser process.
  2. A validation error should appear as the $.Input.access_token field no longer exists. Instead of passing in the current access token value to the GetAuthenticatedUser process, we can just make a call inside of the GetAuthenticatedUser process to the RetrieveToken process.
  3. We can then use the token details returned for the Authorization header of the CallRESTEndpoint like below:
    ="Bearer " +   RetrieveToken.token.access_token

Now when re-initiate the flow, the generated token will be logged in a file. When the user details are requested, the latest token details are retrieved from the local text file and submitted with the request.

You’re set to go!

If you’ve followed the above guide, you should have a better understanding of the OAuth 2.0 flow as well as have a practical understanding of building a basic OAuth 2.0 authenticator with Linx. Hopefully, you should now be able to connect to your API of choice using the above tutorial as a base template.

Look out for more samples and post in the Linx Community.

Need help?

For personal support queries, please contact or reply on this article.