refreshToken
The refreshToken method obtains a new access token using the refresh token. This is used when the current access token has expired but the refresh token is still valid.
This method is accessed via authClient.refreshToken() and automatically updates the stored tokens with the new values.
Method Signature
refreshToken(): Promise<Token | null>
Parameters
This method doesn't accept any parameters. It automatically uses the refresh token stored in localStorage.
Return Value
Returns Promise<Token | null>:
Tokenobject containing the new access token and related data if successfulnullif there's no refresh token available or the refresh fails
Token Object Structure
interface Token {
access_token: string; // New access token for API requests
refresh_token: string; // New or same refresh token
id_token: string; // New 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
- Retrieves the current refresh token from localStorage
- Makes a POST request to
/api/auth/oauth2/tokenwithgrant_type=refresh_token - Receives new tokens from the server
- Updates localStorage with the new token set
- Returns the new token object
Usage
Basic Usage
import { authClient } from "@/auth";
async function refreshAccessToken() {
const newToken = await authClient.refreshToken();
if (newToken) {
console.log("Token refreshed successfully");
console.log("New access token:", newToken.access_token);
} else {
console.log("Failed to refresh token");
}
}
Automatic Token Refresh
Implement automatic token refresh before expiration:
import { authClient } from "@/auth";
import { useEffect } from "react";
function TokenRefreshManager() {
useEffect(() => {
const checkAndRefreshToken = async () => {
const token = authClient.token();
if (!token) return;
// Calculate time until token expires
const expiresAt = Date.now() + token.expires_in * 1000;
const timeUntilExpiry = expiresAt - Date.now();
// Refresh if less than 5 minutes remaining
if (timeUntilExpiry < 5 * 60 * 1000) {
console.log("Token expiring soon, refreshing...");
await authClient.refreshToken();
}
};
// Check every minute
const interval = setInterval(checkAndRefreshToken, 60 * 1000);
// Check immediately on mount
checkAndRefreshToken();
return () => clearInterval(interval);
}, []);
return null;
}
// Use in your app
function App() {
return (
<>
<TokenRefreshManager />
{/* Rest of your app */}
</>
);
}
Refresh on API Error
Retry failed API requests after refreshing the token:
import { authClient } from "@/auth";
async function fetchWithTokenRefresh(url: string) {
try {
// Try the request with current token
const response = await authClient.$fetch(url);
if (!response.ok && response.status === 401) {
// Token expired, try to refresh
console.log("Token expired, refreshing...");
const newToken = await authClient.refreshToken();
if (newToken) {
// Retry the request with new token
return await authClient.$fetch(url);
} else {
throw new Error("Failed to refresh token");
}
}
return response;
} catch (error) {
console.error("Request failed:", error);
throw error;
}
}
With User Feedback
import { authClient } from "@/auth";
import { useState } from "react";
function RefreshTokenButton() {
const [refreshing, setRefreshing] = useState(false);
const [message, setMessage] = useState<string>("");
const handleRefresh = async () => {
setRefreshing(true);
setMessage("");
try {
const newToken = await authClient.refreshToken();
if (newToken) {
setMessage("Token refreshed successfully!");
} else {
setMessage("Failed to refresh token. Please sign in again.");
}
} catch (error) {
setMessage(error instanceof Error ? error.message : "Unknown error");
} finally {
setRefreshing(false);
}
};
return (
<div>
<button onClick={handleRefresh} disabled={refreshing}>
{refreshing ? "Refreshing..." : "Refresh Token"}
</button>
{message && <p>{message}</p>}
</div>
);
}
Scheduled Refresh
Set up a scheduled refresh before the token expires:
import { authClient } from "@/auth";
import { useEffect, useRef } from "react";
function useAutoRefreshToken() {
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
const scheduleRefresh = () => {
const token = authClient.token();
if (!token) return;
// Calculate when to refresh (5 minutes before expiry)
const refreshTime = (token.expires_in - 5 * 60) * 1000;
// Clear any existing timeout
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
// Schedule the refresh
timeoutRef.current = setTimeout(async () => {
console.log("Auto-refreshing token...");
const newToken = await authClient.refreshToken();
if (newToken) {
console.log("Token refreshed successfully");
// Schedule the next refresh
scheduleRefresh();
} else {
console.log("Failed to refresh token");
}
}, refreshTime);
};
scheduleRefresh();
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
}
// Usage
function App() {
useAutoRefreshToken();
return <div>{/* Your app content */}</div>;
}
Error Handling
The method may return null or throw errors in the following cases:
- No refresh token: Returns
nullif there's no refresh token in localStorage - Invalid refresh token: Returns
nullif the refresh token is expired or invalid - Network errors: Throws an error for network issues
- Server errors: Throws an error if the auth server returns an error
Always check for null and handle errors appropriately:
try {
const newToken = await authClient.refreshToken();
if (!newToken) {
// Refresh token expired or invalid
// Redirect to login
window.location.href = "/login";
}
} catch (error) {
console.error("Failed to refresh token:", error);
// Handle error
}
When to Refresh
Refresh the token when:
- The access token is about to expire (recommended: 5 minutes before expiry)
- An API request returns a 401 Unauthorized error
- The user explicitly requests a refresh
Don't refresh the token when:
- The user is not authenticated
- The refresh token itself has expired (redirect to login instead)
- There's no refresh token available
Token Expiration
The expires_in field in the token object indicates how many seconds the access token is valid for. Common values:
- 3600 (1 hour) - Most common
- 86400 (24 hours) - Long-lived tokens
- 300 (5 minutes) - Short-lived tokens for testing
See Also
- Token function - Retrieve current stored tokens
- signIn function - Initial authentication
- signOut function - Sign out and clear tokens
- $fetch function - Make authenticated API requests