Closed Damcios-s closed 1 month ago
Hi, you can still use the old getLogtoContext
method to get access token for now, but it is deprecated and will be removed in the future.
The problem is that HTTP does not allow setting cookies after streaming starts, so we can not cache the access token in the cookie-based session, and resulting the caching failure of access tokens. See the next.js documentation to learn more: https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options.
And for the usage of new "getAccessToken" method, please refer to this: https://docs.logto.io/quick-starts/next-app-router/#fetch-access-token-for-the-api-resource
Hi, thanks for the reply. I've read both these pieces of documentation, and I think I understand what is happening, but I feel like I'm missing something or an important use case is not covered here.
Correct me if I'm wrong on any of these points below:
The logto docs show how to use the "getAccessToken" method in client components such that it is called as a server action. This means when a page is rendered on the server the access token is not fetched, and only once the page is loaded in the browser will the "getAccessToken" server-action be called, be it with useEffect or a user action (onClick etc).
This means that if I need to load a page that shows data that needs to be fetched from a protected api endpoint, I first need to load the page without the data and then call a server actions to fetch the data and render it to the page later. Even though I already know the user is authenticated while rendering the page I cannot get the access token.
What I'm looking for is getting the access token on the initial page load without having to do a second api call / server action from the browser. I've tried to call "getAccessToken" in middleware but that does not work either:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { getAccessToken, getLogtoContext } from "@logto/next/server-actions";
import { logtoConfig } from "@/app/logto";
export async function middleware(request: NextRequest) {
const { isAuthenticated, claims } = await getLogtoContext(logtoConfig);
if (!isAuthenticated) {
return NextResponse.redirect(new URL("/login", request.url));
}
const accessToken = await getAccessToken(
logtoConfig,
"http://registrar:8200/api/admin/v1"
);
return NextResponse.next();
}
Maybe I'm missing a good reason why this use case is not supported, or maybe I'm just missing how to do this correctly.
You are right, currently it is not able to get access token on the server side (RSC), the root cause is the "stateless" cookie-based session, which makes it hard to update the session value. Maybe we'll need to introduce an option to use other session providers.
One temperory solution is to use getLogtoContext
in RSC, until we figure out a better method.
Hi, we introduced a new function getAccessTokenRSC
, the documentation is not ready yet, you can checkout this https://github.com/logto-io/docs/pull/761
Describe the bug
The new getAccessToken() server action to get the access token:
Results in the following error when called on the server:
tA [Error]: Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options
Expected behavior
The old, deprecated way of getting the access token works in the same context:
I would expect the new function to also work in the same context.
How to reproduce?
Create a new Next.js application and set up LogTo. Make a new page.tsx file:
Context
"@logto/next": "^3.4.0" "next": "14.2.5",
Intended behavior ?
If this is the intended behavior now, what would be the correct way to get the access token on the server when loading a page - so NOT in a route handler or a server-action? This is quite an important use case for me as I would rather not have to call my backend twice for loading a page that needs authorized data if the user is already signed in.