@phila/sso-vue
| Install | |
|---|---|
npm install @phila/sso-vue |
|
| Latest Version: | 0.3.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Jul 24, 2026 |
| Links: | npm |
@phila/sso-vue
Vue 3 adapter for @phila/sso-core. Provides a Vue plugin, Pinia store, and composables for Azure AD B2C authentication.
Installation
pnpm add @phila/sso-vue @phila/sso-core @azure/msal-browser pinia
Quick Start (Vite + B2C)
The createB2CPlugin factory reads VITE_SSO_* keys off the import.meta.env you pass it:
VITE_SSO_CLIENT_ID=your-client-id
VITE_SSO_TENANT=YourTenant
VITE_SSO_AUTHORITY_DOMAIN=YourTenant.b2clogin.com
VITE_SSO_REDIRECT_URI=http://localhost:3000
// main.ts
import { createApp } from "vue";
import { createPinia } from "pinia";
import { createB2CPlugin } from "@phila/sso-vue";
import App from "./App.vue";
const app = createApp(App);
app.use(createPinia());
app.use(createB2CPlugin({ env: import.meta.env }));
app.mount("#app");
envmust be passed from your own app's source (i.e. literally writeimport.meta.envat the call site). This package ships pre-built, so it can't read your app's env vars itself —import.meta.env.VITE_SSO_*only resolves when Vite processes it as part of your build.
<!-- App.vue -->
<script setup lang="ts">
import { useAuth } from "@phila/sso-vue";
const { isAuthenticated, userName, authReady, signIn, signOut } = useAuth();
</script>
<template>
<div v-if="!authReady">Loading...</div>
<div v-else-if="isAuthenticated">
<p>Welcome, {{ userName }}</p>
<button @click="signOut()">Sign out</button>
</div>
<div v-else>
<button @click="signIn()">Sign in</button>
</div>
</template>
Advanced Setup
For full control over the provider configuration:
import { createSSOPlugin } from "@phila/sso-vue";
import { B2CProvider } from "@phila/sso-core";
app.use(
createSSOPlugin({
clientConfig: {
provider: new B2CProvider({
clientId: "your-client-id",
b2cEnvironment: "YourTenant",
authorityDomain: "YourTenant.b2clogin.com",
redirectUri: "http://localhost:3000",
apiScopes: ["https://YourTenant.onmicrosoft.com/api/read"],
policies: {
signUpSignIn: "B2C_1A_SIGNUP_SIGNIN",
signInOnly: "B2C_1A_AD_SIGNIN_ONLY",
resetPassword: "B2C_1A_PASSWORDRESET",
},
}),
debug: true,
},
}),
);
Plugin Options
interface SSOPluginOptions {
clientConfig: SSOClientConfig;
autoInitialize?: boolean; // default: true
}
Composables
useAuth()
Primary composable for authentication. Must be called after the plugin is installed.
Reactive state:
| Property | Type | Description |
|---|---|---|
isAuthenticated |
Ref<boolean> |
User is signed in |
isLoading |
Ref<boolean> |
Auth operation in progress |
user |
Ref<AccountInfo | null> |
MSAL account info |
token |
Ref<string | null> |
Current access token |
error |
Ref<Error | null> |
Last auth error |
activePolicy |
Ref<string | null> |
Active B2C policy |
authReady |
Ref<boolean> |
Initialization complete |
userName |
ComputedRef<string | null> |
Display name from token claims |
Actions:
| Method | Returns | Description |
|---|---|---|
signIn(options?) |
Promise<void> |
Start sign-in flow |
signInCityEmployee(options?) |
Promise<void> |
Sign in with sign-in-only policy |
signOut(options?) |
Promise<void> |
Sign out |
forgotPassword() |
Promise<void> |
Start password reset |
acquireToken(options?) |
Promise<string | null> |
Get access token |
Utilities:
| Method | Returns | Description |
|---|---|---|
hasRole(role) |
boolean |
Check user role from roles or extension_Roles claim |
useSSOClient()
Returns the raw SSOClient instance for advanced use cases (direct event subscription, etc.).
const client = useSSOClient();
client.events.on("auth:tokenAcquired", token => {
/* ... */
});
useSSOStore()
Direct access to the Pinia store. Useful when you need store-level reactivity outside of components.
import { useSSOStore } from "@phila/sso-vue";
const store = useSSOStore();
watch(
() => store.isAuthenticated,
val => {
/* ... */
},
);
createB2CPlugin Options
interface B2CPluginOptions {
env: ImportMetaEnv; // required — pass your app's import.meta.env
signInPolicy?: string; // default: "B2C_1A_AD_SIGNIN_ONLY"
resetPasswordPolicy?: string; // default: "B2C_1A_PASSWORDRESET"
debug?: boolean; // default: env.DEV
}
Broker Plugin
createBrokerPlugin is the Vue 3 plugin for apps that integrate with the phila-identity OAuth broker directly. It installs a BrokerClient (from @phila/sso-core) instead of MSAL, so there is no @azure/msal-browser dependency and no B2C policy configuration needed. The Pinia store and composable shapes are intentionally close to the B2C equivalents so switching is mostly find-and-replace.
Use this when your app is registered with the phila-identity broker. Use createSSOPlugin / createB2CPlugin when your app talks to B2C, Entra, or CIAM directly.
Quick Start
// main.ts
import { createApp } from "vue";
import { createPinia } from "pinia";
import { createBrokerPlugin } from "@phila/sso-vue";
import App from "./App.vue";
const app = createApp(App);
app.use(createPinia());
app.use(
createBrokerPlugin({
clientConfig: {
brokerUrl: import.meta.env.VITE_BROKER_URL, // e.g. "https://identity.phila.gov"
clientId: import.meta.env.VITE_CLIENT_ID,
redirectUri: window.location.origin + "/",
scopes: ["openid", "email"],
},
}),
);
app.mount("#app");
<!-- App.vue -->
<script setup lang="ts">
import { useBrokerAuth } from "@phila/sso-vue";
const { isAuthenticated, userName, authReady, signIn, signOut } = useBrokerAuth();
</script>
<template>
<div v-if="!authReady">Loading...</div>
<div v-else-if="isAuthenticated">
<p>Welcome, {{ userName }}</p>
<button @click="signOut()">Sign out</button>
</div>
<div v-else>
<button @click="signIn()">Sign in</button>
</div>
</template>
Plugin Options
interface BrokerPluginOptions {
clientConfig: BrokerClientConfig; // Passed directly to BrokerClient — see @phila/sso-core.
autoInitialize?: boolean; // Default: true. Set false to call initialize() yourself.
}
useBrokerAuth()
Primary composable for broker-authenticated apps. Must be called after createBrokerPlugin() is installed.
Reactive state:
| Property | Type | Description |
|---|---|---|
isAuthenticated |
Ref<boolean> |
User is signed in |
isLoading |
Ref<boolean> |
Auth operation in progress |
user |
Ref<BrokerUser | null> |
User object from /v1/auth/userinfo |
token |
Ref<string | null> |
Current access token |
setupPasskeyToken |
Ref<string | null> |
setup_passkey token from the broker; non-null when passkey:setup scope was granted |
error |
Ref<Error | null> |
Last auth error |
authReady |
Ref<boolean> |
True once initialize() has completed |
userName |
ComputedRef<string | null> |
Display name derived from given_name + family_name, falling back to name |
Actions:
| Method | Returns | Description |
|---|---|---|
signIn(options?) |
Promise<void> |
Start the PKCE flow |
signOut(options?) |
Promise<void> |
Clear the local session and redirect |
acquireToken(options?) |
Promise<string | null> |
Return the current access token, refreshing if near expiry |
Utilities:
| Method | Returns | Description |
|---|---|---|
hasRole(role) |
boolean |
Check for a role in the user's roles claim |
useBrokerStore()
Direct access to the Pinia store. Useful when you need store-level reactivity outside of components.
import { useBrokerStore } from "@phila/sso-vue";
const store = useBrokerStore();
watch(
() => store.isAuthenticated,
val => {
/* ... */
},
);
Resource-bound tokens
To get a token scoped to a downstream API, pass resource either at plugin config time (all sign-ins) or per sign-in:
// Per sign-in override:
await signIn({ scopes: ["openid", "api:access"], resource: "https://my-api.example.com" });
// Then call the API with the access_token:
const { token } = useBrokerAuth();
fetch("https://my-api.example.com/data", {
headers: { Authorization: `Bearer ${token.value}` },
});
License
MIT
Related Packages
Vue plugin for using Microsoft Authentication Library (MSAL 2.0) (forked from vu...
Vue plugin for using Microsoft Authentication Library (MSAL 2.0) (forked from vu...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.3.0 | ^3.0.0 | MIT | |
| 0.2.0 | ^3.0.0 | MIT | |
| 0.1.0 | ^3.0.0 | MIT | |
| 0.0.9 | ^3.0.0 | MIT | |
| 0.0.8 | ^3.0.0 | MIT | |
| 0.0.7 | ^3.0.0 | MIT | |
| 0.0.6 | ^3.0.0 | MIT | |
| 0.0.5 | ^3.0.0 | MIT | |
| 0.0.4 | ^3.0.0 | MIT | |
| 0.0.3 | ^3.0.0 | MIT | |
| 0.0.2 | ^3.0.0 | MIT | |
| 0.0.1 | ^3.0.0 | MIT |