Skip to main content

Access Data Using Sessions

This guide will show you how to implement a session authorization flow to grant temporary elevated access to your frontend applications using sessions.

Key concepts in this guide:

Getting Started

To get started, you will need a Basis Theory account.

Create a Public Application

Next you will need a Public Application that will be used within our frontend web or mobile application. We will be granting this Public Application just-in-time access to read a token within our frontend application using Sessions.

If you do not already have a Public Application, click here to create one.

Save the API Key from the created Public Application as it will be used later in this guide.

Create a Private Application

Next you will need a Private Application that will be used within our backend service. We will be using this private application to create a token and authorize a session to read this token, so ensure that you have granted at least the token:create and token:read permissions.

If you do not already have a Private Application with these permissions, click here to create one.

Save the API Key from the created Private Application as it will be used later in this guide.

Create a Token

In order to have a token available to reveal to our frontend application in later steps, we will first create a token. For simplicity, we are creating this token through the Basis Theory API using the Private Application created above, however you can imagine this token could have been collected by a frontend application using Elements.

Run the following in your terminal to create the token:

curl "https://api.basistheory.com/tokenize" \
-X "POST" \
-H "BT-API-KEY: <PRIVATE_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"type": "token",
"data": {
"first_name": "Luke",
"last_name": "Skywalker",
"social_security_number": "111-22-3333",
"email_address": "luke@skywalkerranch.com"
},
"containers": [ "/" ]
}'
Be sure to replace <PRIVATE_API_KEY> with the Private API Key you created in the Create a Private Application step.

Create a Session

The first step in the session authorization flow begins with creating a session in the frontend application. This endpoint returns a session_key, which can later be used within the BT-API-KEY header to authenticate against the Basis Theory API, and a nonce, which is a one-time use code that will be used to authorize this session.

The following examples illustrate how to create a session through the Elements SDKs, but you can also call the API directly.

// using the CDN-based version of the basis-theory-js SDK
const bt = await BasisTheory.init("<PUBLIC_API_KEY>");

const { sessionKey, nonce } = await bt.sessions.create();
Be sure to replace <PUBLIC_API_KEY> with the Public API Key you created in the Create a Public Application step.

At this point, the session has not yet been authorized and attempts to use the session_key will be rejected by the API.

Authorize the Session

Next, we will use the nonce to authorize the session. To do this, we will create a secure server-side endpoint to authorize our session.

Creating a Server-Side Endpoint

For illustrative purposes, we show an example of an HTTP-based API with JSON content, written in Node.js + Express and using the Node.js SDK, but you are free to implement this step in any language and technology of your choice. You could even integrate the authorize session operation into another existing API endpoint, if desired.

The key point is that your frontend application will need to provide the one-time use nonce to this server-side endpoint so that it can be forwarded to the Basis Theory authorize session API using the Private API Key created earlier to authenticate.

// example server-side application using Node.js + Express

const express = require("express");
const bodyParser = require("body-parser");
const app = express();

const { BasisTheory } = require("@basis-theory/basis-theory-js");
let bt;

app.use(bodyParser.json());

app.post("/authorize-session", async (request, response) => {
if (!bt) {
bt = await new BasisTheory().init("<PRIVATE_API_KEY>");
}

const { nonce } = request.body;

// authorizing a session returns an empty 200 response
await bt.sessions.authorize({
nonce: nonce,
rules: [
{
description: "Allow reading only our token",
priority: 1,
conditions: [
{
attribute: "id",
operator: "equals",
value: "token_id_1234567890",
},
],
permissions: ["token:read"],
transform: "reveal",
},
],
});

// this response is arbitrary and not required
response.json({
result: "success",
});
});
Be sure to replace <PRIVATE_API_KEY> with the Private API Key you created in the Create a Private Application step, and token_id_1234567890 with the id of the token created in the Create a Token step.

Passing the nonce to the Server-Side Endpoint

This step is entirely up to you to implement in your frontend framework of choice based on how you typically interact with your APIs.

The following example shows how to call our example /authorize-session endpoint within a JavaScript environment using fetch.

const bt = await BasisTheory.init("<PUBLIC_API_KEY>");

const { sessionKey, nonce } = await bt.sessions.create();

// note: you would typically also provide some form of authentication on this request to your backend
await fetch("https://my-api-is-hosted-here.com/authorize-session", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ nonce }),
});

Notes and Best Practices

  • You must implement some server-side method for authorizing sessions in order to access the Private API Key - only Private Applications can authorize sessions.
  • Your server-side endpoint should use some form of authentication to guarantee that sessions are only authorized for known users in your system.
  • Your server-side endpoint should apply some form of authorization logic to ensure that sessions are only granted access to tokens that should be accessible to the authenticated user.
  • Follow the principle of least privilege. In particular, try to only grant token:read or token:use access to specific tokens using conditions, and avoid granting access to entire containers of tokens.

Retrieve the Token

Finally, let's retrieve our token using our newly authorized Session Key.

Retrieving the Token from the API

First, let's run the following curl command in your terminal to inspect the raw HTTP response returned from the API:

curl "https://api.basistheory.com/tokens/token_id_1234567890" \
-H "BT-API-KEY: <SESSION_API_KEY>"
Be sure to replace <SESSION_API_KEY> with the Session Key you received when creating a session and token_id_1234567890 with the id of the token created in the Create a Token step.

You should see a JSON response similar to:

{
"id": "token_id_1234567890",
"type": "token",
"tenant_id": "306b9c97-f974-4a87-b7b5-7f286333c4a4",
"created_by": "51df57ce-ef0f-47ff-b523-a08ecb9bad8a",
"created_at": "2022-12-22T15:07:46.6158347+00:00",
"data": {
"first_name": "Luke",
"last_name": "Skywalker",
"social_security_number": "111-22-3333",
"email_address": "luke@skywalkerranch.com"
},
"containers": ["/"]
}

Notice that plaintext token data is returned from the API since we authorized this session to have the token:read permission and a reveal transform. If we were to make this same request with the original Public API Key instead of the Session Key, the request would have failed with a 403 error since the Public Application was not permitted to read tokens.

Retrieving the Token in the Frontend

Next, we will illustrate how the frontend application could use the Session Key to natively retrieve the token in plaintext.

// using the basis-theory-js SDK initialized with elements: false
const token = await bt.tokens.retrieve(tokenId, {
apiKey: sessionKey,
});

const plaintextTokenData = token.data;
The code shown above retrieves the plaintext token data so that it is directly accessible within your frontend code. This will result in your frontend application being pulled into compliance scope!

If you would like to securely display sensitive data within a frontend application while keeping your code out of compliance scope, you should use Elements to reveal sensitive data that was retrieved using a session. Check out our guide to learn more!

Conclusion

🎉 You now know how to implement a session authorization flow within your system to start using sessions within your frontend applications!

Sessions enable you to securely retrieve tokens within your frontend applications to reveal data within Elements, or they can be used enhance the security within Public Applications when performing any token operation.

Learn More