npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@weareyipyip/multitab-token-refresh

v2.0.2

Published

Refresh tokens with a single tab, use the tokens with multiple tabs.

Downloads

60

Readme

Multitab Token Refresh

When using single-use refresh tokens with multiple browser tabs, a race condition between tabs may occur when it's time to refresh.

This little package solves this problem by using the Web Locks API to synchronize requests for an access token, from multiple browser tabs. If the access token needs refreshing, it is refreshed while the lock is held. This ensures that a refresh token is only used once.

Additionally, this package can provide updates on login/logout events to peer tabs, so that they may transition to an appropriate state.

Setup

We use Axios as an HTTP client in the example.

// ApiService.js
import Axios from "axios";
import {
  fromJwt,
  TokenService,
  Tokens,
  createAxiosAuthRequestInterceptor,
} from "@weareyipyip/multitab-token-refresh";

// ApiClient will be used for requests that don't require an access token
const ApiClient = Axios.create();

// you need to process your own login/refresh response body format and create a new Tokens object from it
// you can use the fromJwt helper function to do so
function authResponseToTokens(resp) {
  const {
    data: { access, refresh },
  } = resp;
  const tokens = fromJwt({ accessToken: access, refreshToken: refresh });
  return tokens;
}

// define a function that can refresh tokens based on a refreshToken and returns a new Tokens object on success
function refreshTokens(refreshToken) {
  return (
    ApiClient.post("/refresh", null, {
      headers: { authorization: `Bearer ${refreshToken}` },
    })
      // on success, map the response to a Tokens object
      .then(authResponseToTokens)
      // on refresh failure, rethrow the error
      // note that we take care to only call setLoggedOut on 401, so that sessions are
      // not logged-out on temporary errors like 503 Service Unavailable
      .catch((authError, setLoggedOut) => {
        if (authError?.response?.status === 401) setLoggedOut();
        throw authError;
      })
  );
}

// Create a TokenService instance
const myTokenService = new TokenService(refreshTokens);

// on login, your need to notify the TokenService of the new status
function onLogin(response) {
  myTokenService.setStatus(authResponseToTokens(response));
  return response;
}

// your login function
function login(username, password) {
  return ApiClient.post("/login", { username, password }).then(onLogin);
}

// AuthApiClient will be used for all requests that require an access token
const AuthApiClient = Axios.create();
const axiosAuthRequestInterceptor =
  createAxiosAuthRequestInterceptor(myTokenService);
AuthApiClient.interceptors.request.use(axiosAuthRequestInterceptor);

// on logout, notify the TokenService (regardless of success)
function logout() {
  return AuthApiClient.post("/logout")
    .then(() => myTokenService.setLoggedOut())
    .catch(() => myTokenService.setLoggedOut());
}

// now you're good to go
AuthApiClient.get("/very_secure_endpoint");

Reload peer tabs on login/logout

If you want all browser tabs of your application to reflect logged-in or logged-out status, you can force a reload of peer tabs using subscribeToPeerTabUpdates. This opt-in behavior can be enabled by simply calling this function anywhere during initialization, for example after setting the refresh callback:

import { subscribeToPeerTabUpdates } from "@weareyipyip/multitab-token-refresh";

const myTokenService = new TokenService(refreshTokens);
subscribeToPeerTabUpdates(myTokenService);

Integrate with Vuex

Example for Vue/Vuex 2, but works for Vue/Vuex 3 as well. Will work across tabs.

// store.js
import Vue from "vue";
import Vuex from "vuex";
import { createVuexPlugin } from "@weareyipyip/multitab-token-refresh";
import { myTokenService } from "./ApiService";

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [createVuexPlugin(myTokenService, "updateAuthStatus")],

  state: {
    loggedIn: false,
  },

  mutations: {
    updateAuthStatus: (state, { loggedIn }) => {
      state.loggedIn = loggedIn;
    },
  },
});