最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

nextjs 15 - Update Auth0 session manually in server action - Stack Overflow

programmeradmin1浏览0评论

I am using the nextjs auth0 package ( "@auth0/nextjs-auth0": "^4.0.2", ) and have an implementation where we update the auth0 session object with what we need for our api, i.e additional access and refresh tokens.

The problem I am having is when I need to refresh the access token with our refresh token. This we want to do either within 5 mintues of the access token expiring or when getting a 401, then update the same session with the new tokens. Since the Session data object is a plain object, it seems ok to do it this way.

The problem is that I get the following error after the browser is stale and I reload it. However refreshing works when testing and lowering the expiration. Next complains that we have to update the cookie in a server action or component, but this logic sits in a file with 'use server' at the top.

'use server';
import { auth0 } from '../auth0-config';
import { tokenToExpire } from '../auth-utils';
import { NextResponse } from 'next/server';
import { SessionData } from '@auth0/nextjs-auth0/types';
const BASE_URL = process.env.FISHDATA_API_BASE;


export const fetchApi = async (
  endpoint: string,
  options: FetchOptions = {}
): Promise<Response> => {
  const MAX_RETRIES = 3;
  const retryCount = options.retryCount || 0;

  if (retryCount >= MAX_RETRIES) {
    return NextResponse.rewrite(new URL('/login', process.env.NEXT_PUBLIC_APP_BASE_URL));
  }

  let session = await auth0.getSession();
  if (!session) {
    return NextResponse.rewrite(new URL('/login', process.env.NEXT_PUBLIC_APP_BASE_URL));
  }

  if (!session?.fishdata_access_token) {
    throw new AuthError('No access token found', 401);
  }
  // Always check if token needs refresh
  if (tokenToExpire(session.fishdata_access_token as string)) {
    await refreshToken(session);
    session = await auth0.getSession();
    if (!session?.fishdata_access_token) {
      throw new AuthError('Token refresh failed', 401);
    }
  }

  const requestHeaders: HeadersInit = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${session.fishdata_access_token}`,
    ...(options.headers || {})
  };

  // Make the API request
  const response = await fetch(`${BASE_URL}${endpoint}`, {
    ...options,
    headers: requestHeaders
  });

  // Handle 401 responses
  if (response.status === 401) {
    await refreshToken(session);
    return fetchApi(endpoint, {
      ...options,
      retryCount: retryCount + 1
    });
  }

  return response;
};

const refreshToken = async (session: SessionData) => {
  try {
    const refreshResponse = await fetch(`${BASE_URL}/auth/refresh`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ refresh_token: session.fishdata_refresh_token })
    });

    const host = process.env.NEXT_PUBLIC_APP_BASE_URL;

    if (!refreshResponse.ok) {
      return NextResponse.rewrite(new URL('/login', host));
    }

    const data = await refreshResponse.json();
    if (!data.access_token) {
      throw new Error('No access token in refresh response');
    }

    // Update the session with new tokens
    await auth0.updateSession({
      ...session,
      fishdata_access_token: data.access_token,
      fishdata_refresh_token: data.refresh_token
    });
    return { success: true };
  } catch (error) {
    console.error('Token refresh failed:', error);
    throw error;
  } finally {
    return NextResponse.rewrite(new URL('/login', process.env.NEXT_PUBLIC_APP_BASE_URL));
  }
};
发布评论

评论列表(0)

  1. 暂无评论