oidc-login-plugin

A configurable Vue 3 plugin that adds router guards, axios interceptors, and pinia integration.
1,516
Install
npm install oidc-login-plugin
Latest Version:3.0.0
Vue:3
License:ّISC
Last Updated:Oct 25, 2026
Links: npm
Maintainer: farshidb2011

OIDC Login Plugin for Vue 3

A configurable Vue 3 plugin that provides OIDC authentication with router guards, axios interceptors, and Pinia integration.

Installation

npm install oidc-login-plugin
# or
pnpm add oidc-login-plugin

Peer dependencies

Requires Vue ≥ 3.5.34, Pinia ≥ 4.0.2, and Vue Router ≥ 5 (when using router integration). Pinia 4 also needs @vue/devtools-api:

pnpm add pinia @vue/devtools-api vue-router vue

Integration Modes

The plugin supports three integration modes depending on your auth architecture:

Mode Use case Setup
Full OIDC-only SPA Pass router + axios to app.use(OidcPlugin, …)
Core Pinia/UserManager only Pass pinia + oidc only — no router/axios warnings
Composable Dual-auth / custom guards Core install + import helpers and hooks

Full mode (default)

OIDC-only apps — same behavior as before:

app.use(OidcPlugin, {
  pinia,
  router,
  axios: axiosInstance,
  oidc: { /* ... */ },
});

Core mode

Use only the Pinia UserManager layer. No router guards or axios interceptor are registered:

app.use(OidcPlugin, {
  pinia,
  oidc: { /* ... */ },
  // router and axios omitted intentionally — no warnings
});

Handle the OIDC callback manually with createOidcCallbackHandler or the OidcCallback component.

Composable mode (dual-auth)

For apps that mix OIDC (e.g. staff) with another auth system (e.g. customer JWT), install in Core mode and wire integrations yourself with hooks:

import {
  OidcPlugin,
  setupOidcRouterGuards,
  setupOidcAxiosInterceptor,
} from 'oidc-login-plugin';

// Core install — no global OIDC enforcement
app.use(OidcPlugin, { pinia, oidc: { /* ... */ } });

// Only apply OIDC guards when the session is OIDC
setupOidcRouterGuards(router, {
  redirectUri: oidc.userManagerSettings.redirect_uri,
  hooks: {
    shouldHandleRoute: (to) =>
      to.meta.authMode === 'oidc' || isIdentityJwt(getToken()),
  },
});

// Only refresh OIDC tokens on 401 for OIDC sessions
setupOidcAxiosInterceptor(axiosInstance, {
  hooks: {
    shouldHandleUnauthorized: () => isIdentityJwt(getAuthToken()),
  },
});

You can also disable built-in integrations while still passing instances for manual setup:

app.use(OidcPlugin, {
  pinia,
  router,
  axios: axiosInstance,
  oidc: { /* ... */ },
  features: {
    router: false,
    axios: false,
  },
});

Quick Start

1. Create your router

import { createRouter } from 'vue-router';

const router = createRouter({
  routes: [
    {
      path: '/dashboard',
      component: Dashboard,
      meta: { requiresAuth: true }
    }
  ]
});

2. Install the plugin

Important: Use this plugin BEFORE app.use(router) because it modifies the router by adding guards and routes.

import { createApp } from 'vue';
import { createPinia } from 'pinia';
import axios from 'axios';
import OidcPlugin from 'oidc-login-plugin';
import router from './router';
import App from './App.vue';

const app = createApp(App);
const pinia = createPinia();

const axiosInstance = axios.create({
  baseURL: 'https://api.example.com'
});

// Install Pinia first
app.use(pinia);

// Install OIDC plugin BEFORE router
app.use(OidcPlugin, {
  pinia,
  router,
  axios: axiosInstance,
  oidc: {
    userManagerSettings: {
      authority: 'https://your-idp.com',
      client_id: 'your-client-id',
      redirect_uri: 'http://localhost:3000/callback',
      post_logout_redirect_uri: 'http://localhost:3000',
      response_type: 'code',
      scope: 'openid profile email',
    },
    storageKey: 'authToken',
    redirectUrl: '/login'
  },
  identityAppsUrl: 'https://your-idp.com/apps',
  debug: true
});

// Install router AFTER the plugin
app.use(router);

app.mount('#app');

3. Use the store and composables

import { useUserStore, useGlobal } from 'oidc-login-plugin';

// User store for authentication state
const userStore = useUserStore();
const isAuth = await userStore.isAuthenticated();
const user = userStore.user;

// Global composable for logout with redirect
const { logout } = useGlobal();
logout(); // Logs out and redirects to identityAppsUrl

Important Notes

⚠️ Plugin Installation Order: Always use app.use(OidcPlugin, ...) BEFORE app.use(router) because the plugin modifies the router by:

  • Adding the callback route dynamically based on your redirect_uri
  • Setting up navigation guards for protected routes
  • Configuring authentication flow
// ✅ Correct order
app.use(pinia);
app.use(OidcPlugin, { ... });
app.use(router);

// ❌ Wrong order - guards and routes won't work properly
app.use(router);
app.use(OidcPlugin, { ... });

Features

  • ✅ OIDC authentication with oidc-client-ts
  • ✅ Three integration modes: Full, Core, Composable
  • ✅ Opt-in router guards and axios interceptor via features flags
  • ✅ Customization hooks for dual-auth (shouldHandleRoute, shouldHandleUnauthorized, …)
  • ✅ Tree-shakeable named exports (setupOidcRouterGuards, createOidcCallbackHandler, …)
  • ✅ Automatic callback route registration (no manual route needed)
  • ✅ Built-in callback component with loading UI
  • ✅ Router guards for protected routes (meta: { requiresAuth: true })
  • ✅ Axios interceptor with automatic token refresh on 401
  • ✅ Pinia store for user state management
  • ✅ Global logout with configurable redirect
  • ✅ Configurable storage keys and redirect URLs
  • ✅ Debug mode for development
  • ✅ TypeScript support

How It Works

The plugin automatically:

  1. Registers a callback route - Dynamically adds the callback route based on your redirect_uri configuration
  2. Sets up router guards - Protects routes with meta: { requiresAuth: true } and redirects unauthenticated users to OIDC sign-in
  3. Configures axios interceptor - Adds Bearer token to requests and handles 401 errors with automatic token refresh
  4. Initializes user store - Creates a Pinia store with user state, authentication methods, and UserManager instance

Composable API

Named exports for manual integration:

import {
  useUserStore,
  setupOidcRouterGuards,
  setupOidcAxiosInterceptor,
  createOidcCallbackHandler,
  resolveOidcReturnUrl,
  installSigninSilentDedupe,
  OidcCallback,
} from 'oidc-login-plugin';

Hooks

type OidcIntegrationHooks = {
  /** Return false to skip OIDC handling (dual-auth). */
  shouldHandleRoute?: (to) => boolean | Promise<boolean>;
  /** Return false to skip OIDC refresh on 401. */
  shouldHandleUnauthorized?: (error) => boolean | Promise<boolean>;
  /** Custom redirect when auth fails instead of signinRedirect. */
  onUnauthenticated?: (ctx: { route?; error? }) => void | Promise<void>;
  /** Called after successful token refresh. */
  onTokenRefreshed?: (user) => void | Promise<void>;
  /** Choose which token to persist (access_token vs id_token). */
  selectAccessToken?: (user) => string | null;
};

Pass hooks globally via app.use(OidcPlugin, { hooks }) or per-integration via setupOidcRouterGuards(router, { hooks }).

Documentation

See USAGE.md for detailed documentation.

License

ISC

Related Packages

create-vite-vue

基于Vite+Vue3创建基础项目模板

4,353
vue-axios-plugin

axios plugin for Vuejs project

3,206 58
pinia-plugin-loading

Auto loading data binding plugin for pinia. You don't need to write showLoading...

1,337 12
pinia-plugin-created

create created lifecycle method in your pinia 🍍 store!

284 0
vue-cli-plugin-axios

Vue-cli-3 plugin: axios

226,755

Version History

Version Released Vue License
3.0.0 ^3.5.34 ّISC
2.5.0 ^3.4.0 ّISC
2.4.2 ^3.4.0 ّISC
2.4.1 ^3.4.0 ّISC
2.4.0 ^3.4.0 ّISC