@drmhse/authos-vue
Vue 3 adapter for AuthOS - the multi-tenant authentication platform. Provides Vue composables, components, and Nuxt module.
Quick Start (5 minutes)
npm install @drmhse/authos-vue
Install the plugin and you’re ready to go:
// main.ts
import { createApp } from 'vue';
import { createAuthOS } from '@drmhse/authos-vue';
import App from './App.vue';
const app = createApp(App);
app.use(createAuthOS({
baseURL: 'https://sso.example.com',
}));
app.mount('#app');
<!-- App.vue -->
<script setup>
import { SignIn, SignedIn, SignedOut, UserButton } from '@drmhse/authos-vue';
</script>
<template>
<SignedOut>
<SignIn @success="console.log('Welcome!')" />
</SignedOut>
<SignedIn>
<UserButton />
<p>You're signed in!</p>
</SignedIn>
</template>
That’s it. You now have:
- Email/password authentication with MFA support
- Automatic session management
- User dropdown with logout
- Conditional rendering based on auth state
Usage Modes
AuthOS supports two usage modes:
Platform-Level Access
For platform owners and administrators, use without org/service:
app.use(createAuthOS({
baseURL: 'https://sso.example.com',
}));
Multi-Tenant Access (Organizations)
For tenant applications with OAuth support, add org and service:
app.use(createAuthOS({
baseURL: 'https://sso.example.com',
org: 'acme-corp', // Organization slug
service: 'main-app', // Service slug
}));
Using an Existing Client
For advanced use cases, you can pass a pre-configured SsoClient:
import { SsoClient } from '@drmhse/sso-sdk';
import { createAuthOS } from '@drmhse/authos-vue';
// Create client with custom configuration
const client = new SsoClient({
baseURL: 'https://sso.example.com',
storage: customStorage,
});
app.use(createAuthOS({ client }));
OAuth / Social Login
To use OAuth providers (GitHub, Google, Microsoft), configure your organization and service (see Multi-Tenant Access above):
app.use(createAuthOS({
baseURL: 'https://sso.example.com',
org: 'my-org', // Your organization slug
service: 'my-app', // Your service slug
redirectUri: 'https://app.example.com/callback', // Optional
}));
Then use individual OAuth buttons:
<script setup>
import { OAuthButton } from '@drmhse/authos-vue';
</script>
<template>
<OAuthButton provider="github" />
<OAuthButton provider="google">Sign in with Google</OAuthButton>
<OAuthButton provider="microsoft" />
</template>
Components
SignIn
Complete sign-in form with email/password authentication. Supports scoped slots for custom UI.
<script setup>
import { SignIn } from '@drmhse/authos-vue';
function handleSuccess() {
router.push('/dashboard');
}
</script>
<template>
<SignIn @success="handleSuccess" @error="console.error" />
</template>
Events:
| Event | Payload | Description |
|---|---|---|
@success |
- | Fired after successful login |
@error |
Error |
Fired on login error |
Scoped Slot:
<SignIn v-slot="{ email, password, step, error, isSubmitting, updateEmail, updatePassword, submit }">
<form @submit.prevent="submit">
<input :value="email" @input="e => updateEmail(e.target.value)" />
<input :value="password" type="password" @input="e => updatePassword(e.target.value)" />
<button :disabled="isSubmitting">Sign In</button>
<p v-if="error">{{ error }}</p>
</form>
</SignIn>
SignUp
Registration form for new users.
<SignUp @success="console.log('Check your email!')" @error="console.error" />
MagicLinkSignIn
Sign-in component for Magic Links (passwordless).
<MagicLinkSignIn @success="console.log('Magic link sent!')" />
PasskeySignIn
Sign-in component for Passkeys (WebAuthn).
<PasskeySignIn @success="console.log('Authenticated!')" />
SignedIn / SignedOut
Conditional rendering based on authentication state. Inspired by Clerk’s API.
<SignedIn>
<!-- Only shown when user is logged in -->
<UserButton />
</SignedIn>
<SignedOut>
<!-- Only shown when user is logged out -->
<SignIn />
</SignedOut>
UserButton
User menu button with avatar and logout.
<UserButton @logout="router.push('/')" />
OrganizationSwitcher
Dropdown to switch between organizations.
When switching organizations, the SDK automatically issues new JWT tokens with the new organization context, enabling seamless multi-tenant switching without re-authentication.
<OrganizationSwitcher @switch="org => console.log('Switched to:', org.name)" />
Protect
Conditional rendering based on user permissions.
<Protect permission="admin:access">
<template #default>
<AdminDashboard />
</template>
<template #fallback>
<p>Access denied</p>
</template>
</Protect>
OAuthButton
Individual OAuth provider button. Requires org and service in plugin options.
<OAuthButton provider="github" />
<OAuthButton provider="google">Continue with Google</OAuthButton>
Scoped Slot:
<OAuthButton provider="github" v-slot="{ providerName, isConfigured, handleClick }">
<button @click="handleClick" :disabled="!isConfigured">
Continue with {{ providerName }}
</button>
</OAuthButton>
Composables
useAuthOS
Access the AuthOS client, state, and configuration.
<script setup>
import { useAuthOS } from '@drmhse/authos-vue';
const { client, options, isAuthenticated, isLoading } = useAuthOS();
async function handleLogout() {
await client.auth.logout();
}
</script>
useUser
Get the current user’s profile.
<script setup>
import { useUser } from '@drmhse/authos-vue';
const { user, isLoading } = useUser();
</script>
<template>
<div v-if="isLoading">Loading...</div>
<div v-else>Welcome, {{ user?.email }}</div>
</template>
useOrganization
Get and switch between organizations.
<script setup>
import { useOrganization } from '@drmhse/authos-vue';
const { currentOrganization, organizations, switchOrganization, isSwitching } = useOrganization();
</script>
<template>
<h3>{{ currentOrganization?.name }}</h3>
<ul>
<li v-for="org in organizations" :key="org.id">
<button @click="switchOrganization(org.slug)">{{ org.name }}</button>
</li>
</ul>
</template>
usePermission / useAnyPermission / useAllPermissions
Check user permissions.
<script setup>
import { usePermission, useAnyPermission, useAllPermissions } from '@drmhse/authos-vue';
const canAccessAdmin = usePermission('admin:access');
const canReadOrWrite = useAnyPermission(['read:data', 'write:data']);
const hasFullAccess = useAllPermissions(['read:data', 'write:data', 'delete:data']);
</script>
<template>
<button v-if="canAccessAdmin">Admin Panel</button>
</template>
Nuxt Integration
Plugin Installation
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@drmhse/authos-vue/nuxt'],
});
Auth Middleware
// middleware/auth.ts
import { authMiddleware } from '@drmhse/authos-vue/nuxt';
export default authMiddleware({
redirectTo: '/login',
});
Then use in your pages:
<script setup>
definePageMeta({
middleware: ['auth'],
});
</script>
<template>
<div>Protected page</div>
</template>
Server-Side Usage
// server/api/user.get.ts
import { currentUser } from '@drmhse/authos-vue/nuxt';
export default defineEventHandler(async (event) => {
const user = await currentUser(event);
if (!user) {
throw createError({
statusCode: 401,
message: 'Unauthorized',
});
}
return user;
});
Configuration Reference
createAuthOS Options
| Option | Type | Required | Description |
|---|---|---|---|
baseURL |
string |
Yes | AuthOS API URL |
org |
string |
For OAuth | Organization slug for OAuth flows |
service |
string |
For OAuth | Service slug for OAuth flows |
redirectUri |
string |
- | OAuth redirect URI (defaults to origin + ‘/callback’) |
afterSignInUrl |
string |
- | Redirect URL after sign-in |
afterSignUpUrl |
string |
- | Redirect URL after sign-up |
storage |
TokenStorage |
- | Custom token storage |
autoRefresh |
boolean |
- | Auto-refresh expired tokens (default: true) |
initialToken |
string |
- | SSR token for hydration |
Styling
All components use data attributes for styling hooks:
[data-authos-signin] { /* Container */ }
[data-authos-field="email"] { /* Email field wrapper */ }
[data-authos-field="password"] { /* Password field wrapper */ }
[data-authos-submit] { /* Submit button */ }
[data-authos-error] { /* Error message */ }
[data-authos-oauth] { /* OAuth button */ }
[data-authos-oauth][data-provider="github"] { /* GitHub button */ }
[data-authos-divider] { /* "or" divider */ }
[data-authos-magic-link] { /* Magic Link container */ }
[data-authos-passkey] { /* Passkey container */ }
Migration from v1
If you’re upgrading from v1, note the following breaking change:
app.use(createAuthOS({
- baseUrl: 'https://sso.example.com',
+ baseURL: 'https://sso.example.com',
}));
The baseUrl property has been renamed to baseURL (uppercase URL) for consistency with the React package and underlying SDK.
License
MIT © DRM HSE