Overview
This document is intended to help Partners understand one of the ways they can integrate their application/website with Builtfirst by having their application users auto-logged in/auto-signed up into Builtfirst.
Implementing auto-login/auto-sign up
A community URL supports passing in two query parameters that if passed the user will be auto-logged in or auto-signed up (if the user email that has been passed in the JWT doesn’t exist).
An auto-signed in/auto-signed up URL for the production environment will look like this:
https://[your subdomain].builtfirst.com/?cid=[2]&jwt=[JSON Web Token]
Details about variable parts of the URL
The "cid" part can be obtained on the partner portal by going to a specific community configuration
The “[JSON Web Token]” must be created by the partner application/website so development work is needed, details about how to create it and the information that must be included are provided in a section of this document
JSON Web Token
💡 Builtfirst uses JWT to securely authorize access and exchange information.
💡 To create the JWT a secret key is needed, it can be obtained by going to the community configuration see picture below
When building the JWT make sure you set the following
Header:
typ
: must beJWT
alg
: must beHS256
{
"alg": "HS256",
"typ": "JWT"
}
Claims(all are mandatory):
user_email
: email address of the user. this is our "key" to identifying whether a user exists or notuser_first_name
: The first name of the useruser_last_name
: The last name of the userjti
: stands for JWT ID Claim and should be unique within the span of the valid request window which is currently 3 minutes. We use this to defend against replay attacks.iat
: stands for issued at and is a "now" timestamp in seconds (not milliseconds) since epoch. Requests should be made immediately, but we currently provide a generous leeway and validate that the request is no longer than 3 minutes old.user_external_id
: the Partner's unique identifier for the user. Used for cross-referencing and debugging.company_external_id
: the Partner's unique identifier for the company associated with the user. If there is a matching company_external_id, Builtfirst will add the user to the existing Organization, otherwise, a new Organization will be created (and the user will be added to that new Organization).company_name
: the name of the user's company. Will be used if a new Organization is being created.company_website
: the website of the user's company. Will be used if a new Organization is being created.
Example
{
"user_email": "jane@company.com",
"user_first_name": "Jane",
"user_last_name": "Doe",
"jti": "Xjd83dk5",
"iat": 1639415753,
"user_external_id": "123",
"company_external_id": "456",
"company_name": "Company Inc.",
"company_website": "https://www.company.com"
}
💡 The partner implementing the integration must ensure that the company information that is passed in the JWT for different users of their application/website that belong to the same organization is the same so both users are added to the same organization at Builtfirst when are automatically signed up.
💡 All the auto-created organizations are going to be of type “VC-Backed startup” and are going to have a buyer profile.
Environments
Builtfirst provides 2 environments for integration
TEST
is a test environment that should be used for developing against and testing your integration prior to using the production environment.PROD
is the Builtfirst production environment with real users, accounts, data, etc.
If the TEST environment is needed please contact support to obtain the details that are needed
Example of usage
Include an HTML <iframe> in your application/website so your users can find discounts as if were managed by your website.
HTML
<iframe
src="https://mysubdomain.builtfirst.com/?cid=123&jwt=xYz123"
height="800px"
width="100%">
</iframe>
Example of JWT generator function written in PHP for WordPress
PHP
function generateJwt($user, $secret, $companyExternalId, $companyName, $companyWebsite) {
// Header
$header = json_encode([
'typ' => 'JWT',
'alg' => 'HS256'
]);
$base64UrlHeader = base64UrlEncode($header);
// Payload
$now = time(); $common = array(
'iat' => $now,
'jti' => md5($now . rand())
);
$user_attributes = array(
'user_external_id' => $user->ID,
'user_email' => $user->user_email,
'user_first_name' => $user->user_firstname,
'user_last_name' => $user->user_lastname,
'company_external_id' => get_user_meta( $user->ID, $companyExternalId, true),
'company_name' => get_user_meta( $user->ID, $companyName, true),
'company_website' => get_user_meta( $user->ID, $companyWebsite, true)
);
$payload = json_encode(array_merge($common, $user_attributes));
$base64UrlPayload = base64UrlEncode($payload);
// JWT
$message = $base64UrlHeader . "." . $base64UrlPayload;
$signature = hash_hmac('sha256', $message, $secret, true);
$base64UrlSignature = base64UrlEncode($signature);
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
return $jwt;
}
function base64UrlEncode($text) {
return str_replace(
['+', '/', '='],
['-', '_', ''],
base64_encode($text)
);
}
NodeJs example
const jwt = require("jsonwebtoken");
const crypto = require('crypto')
function generateJwt(payload, jwtKey){
const iat = Math.round(Date.now() / 1000)
const jti = crypto.createHash('md5').update(iat+crypto.randomBytes(256).toString()).digest('base64')
const token = jwt.sign({...payload, iat, jti}, jwtKey, {
algorithm: "HS256",
})
return token
}
const jwtKey = ""
const payload = {
"user_email": "",
"user_first_name": "",
"user_last_name": "",
"user_external_id": "",
"company_external_id": "",
"company_name": "",
"company_website": ""
}
console.log(generateJwt(payload, jwtKey));
Additional Resources