Clerk session handling, JWT verification, token management, and multi-session workflows. Use when implementing session validation, JWT claims customization, token refresh patterns, session lifecycle management, or when user mentions session errors, authentication tokens, JWT verification, multi-device sessions, or session security.
Autonomously configures Clerk session handling, JWT verification, and token management. Use when implementing session validation, JWT claims customization, token refresh patterns, session lifecycle management, or troubleshooting authentication errors.
/plugin marketplace add vanman2024/ai-dev-marketplace/plugin install clerk@ai-dev-marketplaceThis skill is limited to using the following tools:
README.mdexamples/multi-session.tsxexamples/session-debugging.tsexamples/session-refresh.tsscripts/configure-sessions.shscripts/setup-jwt.shscripts/test-sessions.shtemplates/custom-claims.tstemplates/jwt-verification.tstemplates/session-config.tstemplates/session-types.tsPurpose: Autonomously configure, validate, and troubleshoot Clerk session handling, JWT verification, and token management.
Activation Triggers:
Key Resources:
scripts/configure-sessions.sh - Session configuration helperscripts/setup-jwt.sh - JWT template setup and validationscripts/test-sessions.sh - Session testing and verificationtemplates/session-config.ts - Session configuration patternstemplates/jwt-verification.ts - JWT verification middlewaretemplates/custom-claims.ts - Custom JWT claims setuptemplates/session-types.ts - TypeScript type definitionsexamples/multi-session.tsx - Multi-session managementexamples/session-refresh.ts - Session refresh patternsexamples/session-debugging.ts - Debugging utilities# Interactive session configuration
./scripts/configure-sessions.sh
# Options configured:
# - Session lifetime (default, maximum)
# - Multi-session mode (single, multi-device)
# - Refresh token strategy
# - Session activity tracking
# - Secure cookie settings
What it configures:
# Create/update JWT templates for custom claims
./scripts/setup-jwt.sh <template-name>
# Examples:
./scripts/setup-jwt.sh default # Standard user claims
./scripts/setup-jwt.sh hasura # Hasura integration claims
./scripts/setup-jwt.sh supabase # Supabase integration claims
./scripts/setup-jwt.sh custom # Custom business logic claims
Configures:
# Test session validation and JWT verification
./scripts/test-sessions.sh <test-type>
# Test types:
# - basic → Verify session creation and validation
# - jwt-verify → Test JWT signature verification
# - custom-claims → Validate custom claims presence
# - multi-session → Test multi-device session handling
# - refresh → Test token refresh flow
# - expiration → Test session expiration handling
Next.js App Router:
// Use auth() for session access
import { auth } from '@clerk/nextjs/server';
export async function GET() {
const { userId, sessionId, sessionClaims } = await auth();
if (!userId) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Access custom claims
const userRole = sessionClaims?.role;
const orgId = sessionClaims?.org_id;
return Response.json({ userId, role: userRole });
}
Middleware Pattern:
// See templates/jwt-verification.ts for complete implementation
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)']);
export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) {
auth().protect();
}
});
React/Next.js:
import { useAuth, useSession } from '@clerk/nextjs';
function Component() {
const { userId, sessionId } = useAuth();
const { session } = useSession();
// Session properties
const lastActiveAt = session?.lastActiveAt;
const expireAt = session?.expireAt;
// Session management
const handleRefresh = () => session?.touch(); // Extend session
return (
<div>
<p>Session ID: {sessionId}</p>
<p>Expires: {expireAt?.toLocaleString()}</p>
</div>
);
}
Enable multi-session mode:
// See examples/multi-session.tsx for complete implementation
import { useClerk } from '@clerk/nextjs';
function SessionSwitcher() {
const { client } = useClerk();
const sessions = client?.sessions || [];
// Switch between sessions
const switchSession = async (sessionId: string) => {
await client?.setActiveSession(sessionId);
};
// Sign out of specific session
const signOutSession = async (sessionId: string) => {
const session = client?.sessions.find(s => s.id === sessionId);
await session?.remove();
};
return (/* session switcher UI */);
}
Manual verification:
// See templates/jwt-verification.ts
import { verifyToken } from '@clerk/backend';
async function verifySessionToken(token: string) {
try {
const payload = await verifyToken(token, {
secretKey: process.env.CLERK_SECRET_KEY!,
// Optional: custom verification options
authorizedParties: ['https://app.example.com'],
});
return {
valid: true,
userId: payload.sub,
sessionId: payload.sid,
claims: payload,
};
} catch (error) {
return { valid: false, error: error.message };
}
}
Dashboard setup:
{
"metadata": "{{user.public_metadata}}",
"role": "{{user.public_metadata.role}}",
"org_id": "{{org.id}}",
"org_role": "{{org_membership.role}}",
"permissions": "{{org_membership.permissions}}"
}
Access in code:
// See templates/custom-claims.ts
import { auth } from '@clerk/nextjs/server';
const { sessionClaims } = await auth();
const role = sessionClaims?.role as string;
const orgId = sessionClaims?.org_id as string;
const permissions = sessionClaims?.permissions as string[];
Client-side auto-refresh:
// See examples/session-refresh.ts
import { useSession } from '@clerk/nextjs';
import { useEffect } from 'react';
function useSessionRefresh() {
const { session } = useSession();
useEffect(() => {
if (!session) return;
// Refresh session before expiration
const expiresAt = session.expireAt?.getTime() || 0;
const refreshAt = expiresAt - (5 * 60 * 1000); // 5 min before expiry
const now = Date.now();
if (refreshAt > now) {
const timeout = setTimeout(() => {
session.touch(); // Extends session
}, refreshAt - now);
return () => clearTimeout(timeout);
}
}, [session]);
}
import { useSession } from '@clerk/nextjs';
function Component() {
const { session } = useSession();
const extendSession = async () => {
// Touch session to extend lifetime
await session?.touch();
};
return <button onClick={extendSession}>Stay Logged In</button>;
}
Recommended settings:
Verification checklist:
exp claim)iss claim matches Clerk)aud if using multiple apps)Frontend:
Backend:
Problem: User logged out on page refresh
Solutions:
# Check cookie configuration
./scripts/test-sessions.sh basic
# Verify:
# - Domain settings match deployment URL
# - SameSite attribute compatible with architecture
# - Secure flag enabled in production only
Problem: verifyToken throws error
Diagnosis:
./scripts/test-sessions.sh jwt-verify
# Common causes:
# - Wrong CLERK_SECRET_KEY (check .env)
# - Token expired (check exp claim)
# - Issuer mismatch (check iss claim)
# - Invalid signature (token tampered)
Problem: Custom claims undefined in sessionClaims
Fix:
# Verify JWT template configuration
./scripts/setup-jwt.sh custom
# Steps:
# 1. Ensure template is set as default in Dashboard
# 2. User must sign out and sign in again
# 3. Check claim paths match metadata structure
Problem: Wrong session active after sign-in
Solutions:
// See examples/multi-session.tsx
// Force specific session active
await clerk.setActiveSession(sessionId);
// Or restrict to single session in Dashboard:
// Settings → Sessions → Multi-session handling → Single session
Scripts: All scripts in scripts/ directory handle:
Templates: templates/ contains production-ready code for:
Examples: examples/ demonstrates:
CRITICAL: This skill follows strict security rules:
.gitignore protection documented in all setup scriptsSupported Frameworks: Next.js (App Router, Pages Router), React, Express, Fastify, Remix Clerk SDK Version: @clerk/nextjs 5+, @clerk/backend 1+ Version: 1.0.0
Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing APIs, or debugging security issues.