Storing Tokens with Cookies in JavaScript


A short guide on getting started storing Bearer Tokens in your JavaScript based apps and webpages for using cookies.

OAuth Token based authentication is a powerful tool that allows a user to store access credentials on the client side without exposing any sensitive information, such as API keys, which are a good option to use for authentication in browser or mobile development.

Additionally, OAuth Tokens are useful for tools such as Zapier, which tend to prefer or require OAuth Tokens over typical API keys.

In this guide, we will walk through setting up a webpage to handle OAuth 2 authentication for your API calls by storing them as cookies to be referenced whenever an API call is made.


To build this program, we will be using a third party library, Axios, to help us handle HTTP requests. Any request-like library will work here in place of axios, just ensure that the code is changed following its respective syntax. We can add axios to our program with the following line in the header of our HTML:

<script src=""></script>

As mentioned before, we are going to be using cookies to store our generated authentication token, so we can refer back to it for subsequent API calls instead of creating a new one every time. To start, we will add some helper functions to handle cookie management. The first, setCookie, allows us to set a cookie with a key:value pair. The second, getCookie[1], allows us to get the value of a cookie from the key.

As a note, we are using max-age[2] instead of expires as a more modern solution to fit the set expiry of the token. We’re also setting SameSite=Lax[3] and Secure[4] for security precautions, as while our token expires after 12 hours, we still don’t want unauthorized users getting access to it.

// Helper function to store OAuth 2 Cookie
function setCookie(name, value) {
  let maxAge = `;max-age=${12 * 60 * 60}`; // Expire cookie at 12 hours
  document.cookie =
    name + "=" + value + maxAge + ";path=/" + ";SameSite=Lax" + ";Secure";
// Helper function to get cookie value from key
function getCookie(name) {
  let value = "; " + document.cookie;
  let parts = value.split(`; ${name}=`);
  if (parts.length == 2) return parts.pop().split(";").shift();

Generating the Token

Then, we will create the function that will create the token, adapted from the docs reference.

As we are working on client side Javascript, Buffer requires a separate library. Thankfully, most modern browsers support btoa() as a way to Base64 encode strings.

// Function that takes in the base64 encoded parameters and create a JWT
function getToken(key, secret) {
  const params = new URLSearchParams();
  params.append("grant_type", "client_credentials");
  const config = {
    method: "post",
    url: "",
    headers: {
      // Convert key and secret to B64 encoding
      Authorization: `Basic ${btoa(`${key}:${secret}`)}`,
      "Content-Type": "application/x-www-form-urlencoded",
    data: params,
    .then(function (response) {
      // Set the cookie value equal to the returned JWT
    .catch(function (error) {

This will return a JSON Web Token in the .then() response, which we will then use our helper function to save to a cookie. We can then call on this cookie for our future API calls.

Prompting User Submission

Next, we will create a way for the user to input their credentials so that we can generate the token with them. Because we are saving our token as a cookie, the value will be stored in the browser, meaning we should only require input when the cookie has expired instead of at every API call.

In this case, we are using the prompt()[5] method to create a dialog if we detect that the cookie is not set upon loading the page, as it would work with a typical login workflow. An alternative solution might want to use instead is to check if the cookie is set each time the API call is made, to catch edge cases where the token has expired but the page has not been refreshed. In JavaScript, this would require the use of asynchronous functions with tools such as callbacks or promises.

Note: if running locally, be sure to use a browser that stores local cookies. For example, if running the index.html, Chrome will not store the cookie, while Firefox will. If testing locally, it is suggested to use Firefox.

// Check if non-expired cookie, otherwise prompts for input
document.addEventListener("DOMContentLoaded", function() {
  let token = getCookie("token");
  // Check to see if cookie exists
  if (!token) {
    let apiKey = prompt("Please enter Dolby.IO Media Processing API Key:");
    let secret = prompt("Please enter Dolby.IO Media Processing Secret:");
    getToken(apiKey, secret);

To use the token in a Media Processing API call, we can replace the header x-api-key with Authorization: "Bearer <OAUTH_TOKEN>". Remember, we can get the value of our cookie by calling our helper function getCookie. For example, see this enhance request call below:

function enhanceRequest(name) {
  // Create API call
  const config = {
    method: "post",
    url: "",
    headers: {
      // Cookie authorization called here!
      Authorization: `Bearer ${getCookie("token")}`,
      "Content-Type": "application/json",
      Accept: "application/json",
    data: {
      input: "<DOLBYIO_INPUT_URL>",
      output: "<DOLBYIO_OUTPUT_URL>",
  // Send API response
    .then(function (response) {
      let message = { jobId:, fileName: name };
    .catch(function (error) {

It’s typically best practice to test credentials to see if they are valid before saving them, but in this example, we will just add a button to manually delete the cookie from the webpage to reset the value without going through the browser’s configuration pages.

In your HTML:

<button id="resetToken">Reset API Token</button>

In your JavaScript:

document.getElementById("resetToken").onclick = function() {
  setCookie("token", "");

And that’s it! Once the cookie is stored, all API calls will function as normal until the cookie expires or is manually deleted.

Get started by creating your free account today! To read about how to secure your Millicast tokens, read this post.

Griffin Solot-Kehl

Developer Advocate

Griffin Solot-Kehl is a developer advocate from San Francisco. He has a passion for open source technologies, developer onboarding experiences, and good documentation. Outside of the tech world, Griffin loves curating Spotify playlists, trying out new recipes, and perfecting his skincare routine.

Get Started

Drive real-time interactions and engagement with sub-second latency

We are more than just a streaming solutions provider; we are a technology partner helping you build a streaming ecosystem that meets your goals. Get started for free and as you grow, we offer aggressive volume discounts protecting your margins.

Developer Resources

Explore learning paths and helpful resources as you begin development with

Copy link
Powered by Social Snap