# How-to Guide - Building multiple authentication flows
Depending on the various use cases that your connector supports, you may have to build multiple authentication methods. For example, choose OAuth2 Authorization Code Grant when Workato requires impersonation of a particular user during API authentication and also use API keys or client credentials for stable machine-to-machine authentication when supporting data orchestration use cases. However, it's important to note that Workato does not currently support runtime user connections for multi-auth connections.
To achieve multiple authentication flows, Workato's Connector SDK enables you to define segregated and isolated authentication flows within your connector.
AUTHENTICATION METHODS
This guide assumes you have basic knowledge of the other forms of authentication supported in Workato. Ensure you understand other basic forms of authentication in Workato such as OAuth2 and API keys as we reference them in this guide.
# Sample Connector - Stripe
To learn more about this connector, see Stripe API Authentication (opens new window) documentation.
{
title: 'Stripe',
connection: {
fields: [
{
name: "auth_type",
control_type: "select",
pick_list: [["OAuth2", "stripe_oauth2"], ["API Key", "stripe_api_key"]],
extends_schema: true
}
],
authorization: {
type: "multi",
selected: lambda do |connection|
connection["auth_type"]
end,
options: {
stripe_oauth2: {
type: "oauth2",
fields: [
{ name: 'client_id' },
{ name: 'client_secret' },
],
authorization_url: lambda do |connection|
"https://connect.stripe.com/oauth/authorize?scope=read_write"
end,
token_url: lambda do
"https://connect.stripe.com/oauth/token"
end,
apply: lambda do |_, access_token|
headers("Authorization": "Bearer #{access_token}")
end,
},
stripe_api_key: {
type: "custom_auth",
fields: [
{
name: "api_key",
}
],
apply: lambda do |connection|
headers("Authorization": "Bearer #{connection['api_key']}")
end
}
},
},
base_uri: lambda do
"https://api.stripe.com/"
end
},
test: lambda do |connection|
get('/v1/customers', limit: 1)
end,
#More connector code here
}
# Step 1 - Defining common connection fields
When planning for multiple authentication flows for the connector, start by deciding which fields are common across all authentication flows. This could be the API base url, or the target connector environment. Minimally, you must dedicate a field to selecting the authentication type that supports each connection scenario.
The example we use in this discussion, Stripe, has only the authentication type as a common connection field.
- Authentication Type
- The authentication type from a defined picklist.
Has the following important attributes- Schema attribute
extends_schema: true
tells Workato to evaluate the connection schema again when the use changes the value of this field- Picklist values
stripe_oauth2
andstripe_api_key
are important in the subsequent connector definition.
This is done in the fields
key, which accepts an array of hashes. Each hash in this array corresponds to a separate input field.
fields: [
{
name: "auth_type",
label: "Authentication Type",
control_type: "select",
pick_list: [["OAuth2", "stripe_oauth2"], ["API Key", "stripe_api_key"]],
extends_schema: true
}
]
# Step 2 - Defining the pathway to the selected authentication flow
This component informs Workato what to do with the values it receives from the input fields, and what authentication flow to use. It is implemented through the authorization
key. Start by defining the type
of authorization as "multi"
.
authorization: {
type: "multi",
selected: lambda do |connection|
connection["auth_type"]
end,
},
# Step 3 - Defining the various authentication flows
Define the multiple authentication flows within the options
hash that contains all flows for your connector. Implement this through the selected
lambda that receives the connection
argument. This enables you to reference all connection inputs defined in fields
, and expects a string value as the output.
authorization: {
type: "multi",
selected: lambda do |connection|
connection["auth_type"]
end,
options: {
stripe_oauth2: {
type: "oauth2",
fields: [
{ name: 'client_id' },
{ name: 'client_secret' },
],
authorization_url: lambda do |connection|
"https://connect.stripe.com/oauth/authorize?scope=read_write"
end,
token_url: lambda do
"https://connect.stripe.com/oauth/token"
end,
apply: lambda do |_, access_token|
headers("Authorization": "Bearer #{access_token}")
end,
},
stripe_api_key: {
type: "custom_auth",
fields: [
{
name: "api_key",
}
],
apply: lambda do |connection|
headers("Authorization": "Bearer #{connection['api_key']}")
end
}
},
},
Each key in the option
hash must correspond exactly to one possible output value of the selected
lambda. In our case, you can see that the result value of selected
can be either stripe_oauth2
or stripe_api_key
, because they are the only two possible options that we defined in the auth_type
input field. This matches exactly to the keys you defined in the options
hash.
Within each key, you can define further attributes for the authentication flows, such as type
, apply
, acquire
, and others. This enables you to build specific authentication flows based on existing use cases. You can also define an additional key within each option as a nested fields
array, to support the authentication flow for specific fields.
In our example, we define fields client_id
and client_secret
for OAuth2, and the field api_key
for API key authentication. We also define all keys required for an OAuth2 flow within the stripe_oauth2
hash, and all keys required for API key authentication in the stripe_api_key
hash.
Other authentication formats
Refer to the appropriate guides for all authentication format types. Multi-authentication can support any number and type of authentication flow.
# Step 4 - Setting the API's base URI
The API's base URI instructs Workato on the base URL of the API. This key is optional; however, it enables you to provide relative-only paths in the rest of your connector definition through HTTP requests. Learn how to configure your base URI.
base_uri: lambda do
"https://api.stripe.com/"
end
TIP
This lambda function has access to the connection
argument. This is very useful when the base URI of the API changes depending on the user's instance. You can access the connection
argument in the following format:
base_uri: lambda do |connection|
#some code here
end
Additionally, if the base URI changes with the authentication type, you can implement IF-ELSE
structures to change it dynamically, as demonstrated in the following example:
base_uri: lambda do |connection|
if connection['auth_type'] == "stripe_oauth2"
"https://api.stripe.com/"
else
"https://www.stripe.com/api"
end
end
# Step 5 - Testing the connection
After defining the fields and the flows for each authentication option, you must test the new connection. Use the test
key:
test: lambda do |connection|
get('/customers', limit: 1)
end,
The test
key provides an endpoint for sending sample requests using the new credentials from the user. Successful connections get a 200 OK HTTP
response. In the preceding example above, a GET
request to the /api/channels
endpoint returns a 200
response when we have a valid API key.
# Connections SDK reference
For further information about the available keys within the connection
key and their parameters, see the SDK reference.
Last updated: 6/26/2024, 9:52:40 PM