token

The token method retrieves the currently stored authentication tokens from localStorage. It provides access to the access token, refresh token, ID token, and related metadata.

This method is accessed via authClient.token() and uses lazy loading with in-memory caching for optimal performance.


Method Signature

token(): Token | null

Parameters

This method doesn't accept any parameters.


Return Value

Returns Token | null:

  • Token object containing all authentication tokens and metadata if available
  • null if no tokens are stored (user is not authenticated)

Token Object Structure

interface Token {
  access_token: string;     // Access token for API requests
  refresh_token: string;    // Refresh token for obtaining new access tokens
  id_token: string;         // ID token (JWT) with user claims
  token_type: string;       // Token type (usually "Bearer")
  expires_in: number;       // Expiration time in seconds
  scope: string;            // Space-separated granted scopes
}

How It Works

  1. Checks in-memory cache - Returns cached token if available (fast path)
  2. Reads from localStorage - If not cached, reads from vuer_token storage key
  3. Parses the token - Converts the stored string to a Token object
  4. Caches in memory - Stores the token in memory for subsequent calls
  5. Returns the token or null if not found

Usage

Check Authentication Status

import { authClient } from "@/auth";

function checkAuth() {
  const token = authClient.token();

  if (token) {
    console.log("User is authenticated");
    console.log("Access token:", token.access_token);
  } else {
    console.log("User is not authenticated");
  }
}

Access Token for API Requests

import { authClient } from "@/auth";

async function fetchUserData() {
  const token = authClient.token();

  if (!token) {
    throw new Error("Not authenticated");
  }

  const response = await fetch("/api/user", {
    headers: {
      Authorization: `${token.token_type} ${token.access_token}`,
    },
  });

  return response.json();
}

Check Token Expiration

import { authClient } from "@/auth";

function isTokenExpired(): boolean {
  const token = authClient.token();

  if (!token) return true;

  // Calculate expiration time
  const expiresAt = Date.now() + token.expires_in * 1000;
  const isExpired = Date.now() >= expiresAt;

  return isExpired;
}

function getTimeUntilExpiry(): number | null {
  const token = authClient.token();

  if (!token) return null;

  const expiresAt = Date.now() + token.expires_in * 1000;
  const timeRemaining = expiresAt - Date.now();

  return Math.max(0, timeRemaining);
}

Display Token Information

import { authClient } from "@/auth";

function TokenInfo() {
  const token = authClient.token();

  if (!token) {
    return <div>Not authenticated</div>;
  }

  const expiresAt = new Date(Date.now() + token.expires_in * 1000);

  return (
    <div>
      <h3>Token Information</h3>
      <ul>
        <li>Token Type: {token.token_type}</li>
        <li>Scopes: {token.scope}</li>
        <li>Expires: {expiresAt.toLocaleString()}</li>
        <li>Access Token: {token.access_token.substring(0, 20)}...</li>
      </ul>
    </div>
  );
}

Conditional Rendering

import { authClient } from "@/auth";

function ProtectedContent() {
  const token = authClient.token();

  if (!token) {
    return <LoginPrompt />;
  }

  return <SecureContent />;
}

Token-Based Route Guard

import { authClient } from "@/auth";
import { Navigate } from "react-router-dom";

function PrivateRoute({ children }: { children: React.ReactNode }) {
  const token = authClient.token();

  if (!token) {
    // Redirect to login if no token
    return <Navigate to="/login" replace />;
  }

  return <>{children}</>;
}

// Usage
function App() {
  return (
    <Routes>
      <Route path="/login" element={<LoginPage />} />
      <Route
        path="/dashboard"
        element={
          <PrivateRoute>
            <Dashboard />
          </PrivateRoute>
        }
      />
    </Routes>
  );
}

Performance Characteristics

The token() method is optimized for performance:

  1. First call: Reads from localStorage (slower, ~1-2ms)
  2. Subsequent calls: Returns from memory cache (fast, ~0.01ms)
  3. No network requests: Purely local operation
  4. Synchronous: Returns immediately without waiting

This makes it safe to call frequently without performance concerns.


When to Use

Use token() when you need to:

  • Check if the user is authenticated
  • Access the access token for API requests
  • Check token expiration time
  • Get refresh token for token refresh operations
  • Implement custom authentication logic

Consider using alternatives when:

  • In React components: Use useAuth() or useUserinfo() hooks for reactive updates
  • Making API requests: Use $fetch() which adds the token automatically

Storage Details

The tokens are stored in localStorage under the key vuer_token:

  • Storage type: localStorage (persists across browser sessions)
  • Storage key: vuer_token
  • Format: JSON string
  • Accessibility: Same origin only

Security Considerations

  1. Tokens in localStorage

    • Vulnerable to XSS attacks
    • Ensure your application has proper XSS protection
    • Consider using CSP (Content Security Policy) headers
  2. Token Exposure

    • Never log tokens to console in production
    • Don't send tokens via URL parameters
    • Always use HTTPS in production
  3. Token Lifecycle

    • Tokens are cleared on sign out
    • Automatically cleared on 401 errors
    • Persist across browser sessions

Troubleshooting

Token returns null even though user signed in:

  • Check that signIn completed successfully
  • Verify localStorage is not disabled
  • Check browser's localStorage in DevTools

Token seems outdated:

  • The in-memory cache persists across component renders
  • Use refreshToken() to get a new token
  • The cache is cleared on sign out

Token expiration:

  • expires_in represents seconds, not milliseconds
  • Convert to milliseconds: token.expires_in * 1000
  • Implement automatic refresh before expiration

See Also