Create Profiles with Connect
Overview
Users create and update Profiles by interacting with Basis Connect. All of a business's information is attached to its Profile. When querying the Basis API, Profile objects will be the root of all of a business's resources.
Developers will redirect Users to Connect by generating and embedding URIs in, for example, your onboarding workflow or application dashboard. Connect is an OAuth 2.1 application, and the URI that Developers generate will include various parameters related to client authentication, scope, and application initialization. The Connect user interface handles the entire process of connecting to banks and other data sources.
Generating a URI
Initializing Connect requires generating an initialization token and directing your user to the Connect URI. Constructing the HTTPS request entails (a) populating the query parameters after (b) generating an initialization token.
Query parameters
The following query parameters form the request:
Parameter | Required | Description |
---|---|---|
response_type | ✔ | OAuth response code delivery method.code is the only supported response_type . |
client_id | ✔ | The developer's client ID, issued by Basis. |
scope | ✔ | OAuth scope. profile:read is the only currently supported scope, denoting read-only access to the user's Basis Profile. |
redirect_uri | ✔ | The URI for the user to be redirected upon completing the Connect flow. This must be one of the URIs registered with Basis when creating the client. |
state | OAuth 2.0 state parameter. Optional but recommended to prevent CSRF attacks as users return to your workflow. See this OAuth guide for more information. | |
code_challenge | ✔ | OAuth parameter facilitating Proof Key for Code Exchange protocol. See this section of the OAuth guide for more information. NOTE Basis does not support the code_challenge_method parameter: S256 will always be assumed. |
init_token | ✔ | Detail below. |
For deeper understanding of the query parameters, please review the OAuth 2.1 spec or the OAuth 2.0 Simplified guide.
Initialization token
The initialization token is a JWT signed with your client_secret
.
Initialization token header
{
"alg": "HS512",
"kid": "06914d28-f034-4d52-b048-e11024957c11",
"typ": "JWT"
}
Note that the value for kid
should be your client_id
.
Initialization token payload example
{
"exp": 1516249022,
"iat": 1516239022,
"platform_id": "4f2cc69b-576d-4eef-8fde-c36f1841b434",
"client_id": "06914d28-f034-4d52-b048-e11024957c11",
"user_email": "[email protected]",
"user_name": "Garfield",
"company_ein": "12-3456789",
"company_name": "Lasagna Enterprises",
"native_user_id": "555123",
"native_company_id": "333456"
}
The payload includes the following parameters:
Parameter | Type | Note |
---|---|---|
exp | string<timestamp> | Token expiration time, as specified by RFC 7519. |
iat | string<timestamp> | Token issuance time, as specified by RFC 7519. |
platform_id | string<uuid> | Identifier of the banking platform to connect the user to. |
client_id | string<uuid> | Identifier of the client initializing Connect. |
user_email | string<email> | Email of the user completing Connect. |
user_name | string | Full name of the user completing Connect. |
company_ein | string<pattern:\d{9}> | EIN of the business for which a Profile is being created. |
company_name | string | Full legal name of the business for which a Profile is being created. |
native_user_id | string | A user identifier that is meaningful in the Developer's schema, e.g. a primary key for this user in your database. This can assist in reconciling Basis profiles to your users. |
native_company_id | string | A company identifier that is meaningful in the Developer's schema, e.g. a primary key for this company. |
The initialization token can be categorized into several types of information:
Category | Parameters | Purpose |
---|---|---|
Session information | exp ,iat ,platform_id ,client_id | Used to confirm that the token has not expired, authenticate the client, and initialize Connect for a particular platform. |
Profile construction | user_email ,user_name ,company_ein ,company_name | Critical for fraud prevention and ensuring resilient connections to data sources. |
Reconciliation | native_user_id ,native_company_id | Assist the Developer in associating the Profile information with a user or company record in their own application. It is also helpful in support and debugging interactions with Basis. |
Generating Initialization Tokens
The following TypeScript code will generate an initialization token for a redirect URI.
Install packages
npm install jsonwebtoken @types/jsonwebtoken
Code
After the jsonwebtoken
package is installed, you can use this snippet to generate a token. Insert your Basis client credentials where indicated.
import { Buffer } from 'buffer';
import jwt from 'jsonwebtoken';
const BasisCredentials = {
// replace with credentials provided by Basis
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET',
}
const secret = Buffer.from(BasisCredentials.clientSecret, 'base64');
const payload = {
client_id: BasisCredentials.clientId,
user_name: "Jane Doe",
user_email: "[email protected]",
company_name: "Acme Property Holdings, LLC.",
company_ein: "881231234",
native_user_id: 'user-999',
native_company_id: 'company-456',
platform_id: "70a5e5d3-00df-50f2-9f19-544d1f54c4bf", // use GET /institutions
}
const token = jwt.sign(payload, secret, {
algorithm: 'HS512',
expiresIn: '1h',
});
With an encoded token, you can now create a URI which can be embedded in your application. When this URI is navigated to, it will initialize a session in Connect which will guide a user through connecting their accounts at the institution indicated by platform_id
.
const redirect = new URL('https://connect.development.usebasis.co/oauth');
redirect.searchParams.append('client_id', BasisCredentials.clientId);
redirect.searchParams.append('scope', 'profile:read');
redirect.searchParams.append('code_challenge', codeChallenge);
redirect.searchParams.append('redirect_uri', returnUri);
redirect.searchParams.append('state', state);
redirect.searchParams.append('init_token', token);
// the URL object can be rendered with toString()
const href = redirect.toString();
OAuth Exchange
In addition, Connect uses the Proof Key for Code Exchange (PKCE) protocol, which requires that the client generate and store a code_challenge
and code_verifier
. We recommend using a library in your preferred language to manage the OAuth process end-to-end, and perform PKCE.
Once the Connect URI is generated, it can be embedded in your product's UI to direct users to create their business Profile and establish connections. The URI is used with an HTTPS request:
GET /oauth
HOST: connect.development.usebasis.co
The initialization tokens expire, so it is important to generate the token and Connect URI at a time when it is expected to be used. The expiration time is defined by the developer when signing the JWT. We recommend using a short expiry when possible, ideally not exceeding 1 hour.
After the user authorizes your client to access their profile, an auth_code
is generated and returned. The auth_code
can then be exchanged for an access_token
, refresh_token
and profile_id
by calling POST /oauth/token with the authorization_code
grant type and the code_verifier
. It is important to persist the refresh_token
and profile_id
so that you can request new access_token
s in the future.
The access_token
can then be used to query the Basis API for the newly created profile. Since theaccess_token
expires after 60 minutes, the refresh_token
should be used to request a new access_token
by calling POST /oauth/token with the refresh_token
grant type.
OAuth Errors
A number of errors can occur when initializing Connect. For example, the initialization token could be malformed or expired. In these cases, Connect will attempt to redirect the user to the specified redirect URI immediately after initialization, and will encode error information in the query parameters of the redirect URI. General information about this behavior can be found in section 4.1.2.1 of the OAuth specification.
Note: This behavior will not apply when the redirect URI is malformed or incorrect (i.e. not one of your registered redirect URIs) because it is impossible for Connect to safely redirect the user to your domain.
Parameter | Required | Description |
---|---|---|
error | Required | Error code indicating the type of error that occurred. See values below. |
error_description | Optional | Human-readable description providing more details about the error. |
error_uri | Optional | URI pointing to a web page with information about the error. |
state | Required | The client-provided state parameter to maintain state between the request and callback. |
The error
parameter will be one of the following values:
invalid_request
: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check theerror_description
for more details.unauthorized_client
: The client is not authorized to request an authorization code using this method.access_denied
: The resource owner (e.g. a Connect user) or authorization server denied the request.unsupported_response_type
: The authorization server does not support obtaining an authorization code using this method.invalid_scope
: The requested scope is invalid, unknown, or malformed.server_error
: The authorization server encountered an unexpected condition that prevented it from fulfilling the request.temporarily_unavailable
: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
For example, if a user attempts to initialize Connect with an expired initialization token, you will receive the following redirect:
http://example.com/land?error=invalid_request&error_uri=https%3A%2F%2Fwww.ietf.org%2Farchive%2Fid%2Fdraft-ietf-oauth-v2-1-11.html%23section-4.1.2.1&state=d0fc31e4-3613-4810-ada7-821a74e256ba&error_description=Request+included+expired+Initialization+Token.
This redirect encodes the following information:
error
:invalid_request
error_uri
:https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-4.1.2.1
error_description
:Request included expired Initialization Token.
state
:d0fc31e4-3613-4810-ada7-821a74e256ba
You can ignore this error information or consume it as you see fit (e.g. by logging or raising an error).
Updated 2 days ago