Automatic session refresh
AuthKit automatically refreshes expired access tokens in the middleware using the refresh token. This happens transparently without user interaction.- Detects the expired token
- Calls WorkOS to refresh the session
- Updates the session cookie with new tokens
- Continues the request seamlessly
Access tokens are JWT tokens that expire after a set period. Refresh tokens are long-lived and used to obtain new access tokens without re-authentication.
Manual session refresh (server)
UserefreshSession in server actions or API routes to manually refresh the user’s session:
Manual session refresh (client)
Use therefreshAuth method from the useAuth hook to refresh sessions in client components:
Switching organizations
Users can be members of multiple organizations. Use the organization switching APIs to change the active organization context.'use server';
import { switchToOrganization } from '@workos-inc/authkit-nextjs';
export async function switchOrg(organizationId: string) {
try {
const result = await switchToOrganization(organizationId, {
revalidationStrategy: 'path',
});
return { success: true, organizationId: result.organizationId };
} catch (error) {
return { error: 'Failed to switch organization' };
}
}
'use client';
import { useAuth } from '@workos-inc/authkit-nextjs/components';
import { useEffect } from 'react';
export function OrganizationSwitcher({ organizations }: { organizations: Organization[] }) {
const { organizationId, switchToOrganization, loading } = useAuth();
useEffect(() => {
console.log('Current organization:', organizationId);
}, [organizationId]);
const handleSwitch = async (newOrgId: string) => {
const result = await switchToOrganization(newOrgId, {
revalidationStrategy: 'none',
});
if ('error' in result) {
console.error('Switch failed:', result.error);
} else {
console.log('Switched to:', result.organizationId);
}
};
return (
<select
value={organizationId || ''}
onChange={(e) => handleSwitch(e.target.value)}
disabled={loading}
>
{organizations.map((org) => (
<option key={org.id} value={org.id}>
{org.name}
</option>
))}
</select>
);
}
// Revalidate by path (default)
await switchToOrganization('org_123', {
revalidationStrategy: 'path',
returnTo: '/dashboard',
});
// Revalidate by cache tags
await switchToOrganization('org_123', {
revalidationStrategy: 'tag',
revalidationTags: ['user-data', 'org-settings'],
});
// No automatic revalidation
await switchToOrganization('org_123', {
revalidationStrategy: 'none',
});
Refreshing with organization context
Refresh the session and switch organizations simultaneously:Session refresh callbacks
Monitor session refresh events using callbacks in the middleware:Callback data
TheonSessionRefreshSuccess callback receives:
| Property | Type | Description |
|---|---|---|
accessToken | string | The new access token |
user | User | Updated user object |
impersonator | Impersonator | Present if impersonating |
organizationId | string | Current organization context |
onSessionRefreshError callback receives:
| Property | Type | Description |
|---|---|---|
error | unknown | The error that occurred |
request | NextRequest | The original request |
Handling refresh errors
When a session refresh fails (e.g., refresh token expired or revoked), AuthKit automatically:- Deletes the session cookie
- Redirects the user to AuthKit for re-authentication
Getting fresh access tokens
Use theuseAccessToken hook for automatic token management in client components:
useAccessToken hook automatically:
- Fetches the current access token
- Refreshes it when it expires
- Synchronizes with the main auth session
Best practices
The
useAuth hook’s refreshAuth method updates the entire authentication session, while useAccessToken focuses solely on token management.