getUserinfo

The getUserinfo method fetches user information from the OIDC provider's userinfo endpoint. It returns the authenticated user's profile data including name, email, and other claims.

This method is accessed via authClient.getUserinfo() and is typically used when you need to manually fetch or refresh user information.


Method Signature

getUserinfo(): Promise<User | null>

Parameters

This method doesn't accept any parameters.


Return Value

Returns Promise<User | null>:

  • User object if the request is successful and the user is authenticated
  • null if the user is not authenticated or the request fails

User Object Structure

interface User {
  sub: string;              // Unique user identifier (subject)
  name?: string;            // Full name
  email?: string;           // Email address
  picture?: string;         // Profile picture URL
  given_name?: string;      // First name
  family_name?: string;     // Last name
  email_verified?: string;  // Email verification status
}

How It Works

  1. Retrieves the access token from localStorage
  2. Makes a GET request to /api/auth/oauth2/userinfo with the Bearer token
  3. Returns the user data if successful
  4. Handles 401 errors by clearing the token and returning null

Usage

Basic Usage

import { authClient } from "@/auth";

async function fetchUserProfile() {
  const user = await authClient.getUserinfo();

  if (user) {
    console.log("User name:", user.name);
    console.log("User email:", user.email);
  } else {
    console.log("Not authenticated");
  }
}

In a Component

import { authClient } from "@/auth";
import { useState, useEffect } from "react";

function UserProfile() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const loadUser = async () => {
      try {
        const userData = await authClient.getUserinfo();
        setUser(userData);
      } catch (error) {
        console.error("Failed to fetch user info:", error);
      } finally {
        setLoading(false);
      }
    };

    loadUser();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (!user) return <div>Not authenticated</div>;

  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
      {user.picture && <img src={user.picture} alt="Profile" />}
    </div>
  );
}

Manual Refresh

import { authClient } from "@/auth";
import { useState } from "react";

function RefreshableProfile() {
  const [user, setUser] = useState<User | null>(null);
  const [refreshing, setRefreshing] = useState(false);

  const refreshUserInfo = async () => {
    setRefreshing(true);
    try {
      const userData = await authClient.getUserinfo();
      setUser(userData);
    } catch (error) {
      console.error("Failed to refresh user info:", error);
    } finally {
      setRefreshing(false);
    }
  };

  return (
    <div>
      {user && (
        <div>
          <h2>{user.name}</h2>
          <p>{user.email}</p>
        </div>
      )}
      <button onClick={refreshUserInfo} disabled={refreshing}>
        {refreshing ? "Refreshing..." : "Refresh Profile"}
      </button>
    </div>
  );
}

With Error Handling

import { authClient } from "@/auth";
import { useState } from "react";

function UserProfileWithErrors() {
  const [user, setUser] = useState<User | null>(null);
  const [error, setError] = useState<string | null>(null);

  const loadUserInfo = async () => {
    try {
      setError(null);
      const userData = await authClient.getUserinfo();

      if (userData) {
        setUser(userData);
      } else {
        setError("Failed to fetch user information");
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unknown error");
    }
  };

  return (
    <div>
      <button onClick={loadUserInfo}>Load Profile</button>
      {error && <div className="error">{error}</div>}
      {user && (
        <div>
          <h2>{user.name}</h2>
          <p>{user.email}</p>
        </div>
      )}
    </div>
  );
}

When to Use

Use getUserinfo() directly when:

  • You need imperative control over when to fetch user data
  • You're working outside of React components
  • You need to manually refresh user information

Use the useUserinfo() hook instead when:

  • You're in a React component
  • You want automatic fetching on mount
  • You need reactive state management
  • You want built-in loading and error states

Error Handling

The method handles errors as follows:

  • 401 Unauthorized: Automatically clears the stored token and returns null
  • Network errors: Throws an error that should be caught by the caller
  • No token available: Returns null

Authentication Requirement

This method requires a valid access token to be stored in localStorage. If no token is available or the token is invalid, the method will return null.

To ensure the user is authenticated before calling this method:

import { authClient } from "@/auth";

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

  if (!token) {
    console.log("User is not authenticated");
    return null;
  }

  const user = await authClient.getUserinfo();
  return user;
}

Performance Considerations

  • The method makes a network request each time it's called
  • Consider caching the result or using the useUserinfo() hook for better performance
  • The useUserinfo() hook uses Zustand for state management and avoids unnecessary refetches

See Also