Next.js Discord

Discord Forum

Browser sees access token but getAccessToken() doesn't.

Answered
Saltwater Crocodile posted this in #help-forum
Open in Discord
Saltwater CrocodileOP
Hi. I've been playing with Auth0 integration with Nextjs for a while, and basically I want the access token to fetch things from external APIs (I tried one with Java Spring Boot)...

Every time I try 'http://127.0.0.1:3000/auth/access-token' on browser, it shows me a JSON with the token and expiry fine... But every time I try to fetch anywhere within my App router using

const accessToken = await getToken();

(or with scope/audiences), I receive invalid url error
'/auth/access-token'... I vaguely understand the problem: the server doesnt know what to do with the relative url but the browser does, but this getAccessToken() doesn't work even if I make the whole thing a client component.

I tried specifying the whole url using good old javascript fetch:

const res = await fetch("http://127.0.0.1:3000/auth/access-token", {credentials: 'include'});
const obj = await res.json();
console.log(obj);

But this returns a missing session object while the browser still has active session.

AIs say that this is because the server side doesn't read the browser cookies, so it isn't the same session. But at the same time they say this token is stored in HTTPOnly cookie which is stored in server side, which makes sense because otherwise the nextjs server would have to check every time with the browser...

Below is the problematic part of the code (as per console)...


//{root}/src/app/helloapi/page.tsx

import { getAccessToken } from '@auth0/nextjs-auth0';
import React from 'react'

const res = await fetch("http://127.0.0.1:3000/auth/access-token", {credentials: "include"});
const obj = await res.json();

console.log(obj);
export default function page() {
return (
<div>
{JSON.stringify(obj)}
</div>
)
}
const accessToken = await getAccessToken();
console.log(accessToken);
Answered by alfonsüs ardani
try getting the result of auth0.getSession()
View full answer

49 Replies

@Saltwater Crocodile Hi. I've been playing with Auth0 integration with Nextjs for a while, and basically I want the access token to fetch things from external APIs (I tried one with Java Spring Boot)... Every time I try 'http://127.0.0.1:3000/auth/access-token' on browser, it shows me a JSON with the token and expiry fine... But every time I try to fetch anywhere within my App router using const accessToken = await getToken(); (or with scope/audiences), I receive invalid url error '/auth/access-token'... I vaguely understand the problem: the server doesnt know what to do with the relative url but the browser does, but this getAccessToken() doesn't work even if I make the whole thing a client component. I tried specifying the whole url using good old javascript fetch: const res = await fetch("http://127.0.0.1:3000/auth/access-token", {credentials: 'include'}); const obj = await res.json(); console.log(obj); But this returns a missing session object while the browser still has active session. AIs say that this is because the server side doesn't read the browser cookies, so it isn't the same session. But at the same time they say this token is stored in HTTPOnly cookie which is stored in server side, which makes sense because otherwise the nextjs server would have to check every time with the browser... Below is the problematic part of the code (as per console)... //{root}/src/app/helloapi/page.tsx import { getAccessToken } from '@auth0/nextjs-auth0'; import React from 'react' const res = await fetch("http://127.0.0.1:3000/auth/access-token", {credentials: "include"}); const obj = await res.json(); console.log(obj); export default function page() { return ( <div> {JSON.stringify(obj)} </div> ) } const accessToken = await getAccessToken(); console.log(accessToken);
ummm.. i think you're supposed to fetch inside the page() not outside
@alfonsüs ardani ummm.. i think you're supposed to fetch inside the page() not outside
Saltwater CrocodileOP
Thanks, I tried that, still all the same... fetch() still returns the no-active-session json and getAccessToken() still gives the URL parse failure...
AIs say that this is because the server side doesn't read the browser cookies
this is inaccurate

server-side do read browser cookies but it can't automatically send cookies the way browser does if you do call fetch() in the server.

this token is stored in HTTPOnly cookie which is stored in server side

incorrect. httpOnly cookies are stored in the client but are only readable by the server.

---

im not familiar with auth0

I vaguely understand the problem: the server doesnt know what to do with the relative url but the browser does

correct. server's fetch must be absolute url not relative.

but this getToken() doesn't work even if I make the whole thing a client component.

this is weird. why dont it work? if getToken is using relative url then it is most likely meant to be used in the client-side javascript.
.env.local

AUTH0_SECRET='e06e53ebe00b8296e27c46c4d1d95283b7c1f6aaf00672b30daffaa4472e22ed'
APP_BASE_URL='http://127.0.0.1:3000'
AUTH0_BASE_URL='http://127.0.0.1:3000'
AUTH0_DOMAIN='{double checked}'
AUTH0_CLIENT_ID='{double checked}'
AUTH0_CLIENT_SECRET='{double checked}'
//NEXT_PUBLIC_ACCESS_TOKEN_ROUTE='http://localhost:3000/auth/access-token'
//NEXT_PUBLIC_BASE_PATH='http://127.0.0.1:3000'

Commented out NEXT_PUBLIC... variables coz I tried those by looking at the function definition of getAccessToken().... Still invalid url
I thank you for providing the full screenshot
but in addition to that, i might need the error logs too
Saltwater CrocodileOP
Sure, in a moment
What I dont understand is, even from my server I can access the profile using useUser hook

Incorrect. the moment you add "use client", those code, useUser is being run in the client.

From the screenshot that you gave me, i only suspect that getAccessToken is the one causing the Invalid URL and is meant to be used in the client.
Saltwater CrocodileOP
The full console after the dev server start message
@Saltwater Crocodile The full console after the dev server start message
try commenting await getAccessToken()
@alfonsüs ardani try commenting `await getAccessToken()`
Saltwater CrocodileOP
Done, no runtime error but still missing session object when I already have an active session
you might want to find an API in auth0 that works in the server side
otherwise i can only suggests solution that probably aren't recommended by the library
@alfonsüs ardani otherwise i can only suggests solution that probably aren't recommended by the library
Saltwater CrocodileOP
Alright I will try that... Can you suggest potential causes of this issue? Because I still dont think I have figured that out
@Saltwater Crocodile Alright I will try that... Can you suggest potential causes of this issue? Because I still dont think I have figured that out
its because when you access http://127..../auth/access-token from the server, it doesn't have authentication identities as it would if you were to access http://127..../auth/access-token from the client.
from the client, the browser attach relevant cookies (this is where identity is often stored) to every fetch calls.

from the server, it is just plain fetch
@alfonsüs ardani https://auth0.com/docs/quickstart/webapp/nextjs
Saltwater CrocodileOP
Thanks but this documentation doesnt specify how to get the token for an external api...
what do you mean external api
@alfonsüs ardani what do you mean external api
Saltwater CrocodileOP
So basically I have an api defined and active at port 8080 (spring boot)... I'm trying to secure one app (Nextjs) and its api (Spring) with Auth0... And that's a thingg hardly any documentation covers...
it does cover in the docs
its a weird thing, i dont blame you for not knowing but it is the basics of authentication. server-side auth vs client-side auth
this is server-side
Saltwater CrocodileOP
But again it's the same missing piece of the puzzle no? I can get session info but not fetch the token... I still need to specifically send the token to 8080 from server at 3000 that the browser is displaying at /auth/access-token... Right?
I'm still unable to get this thing as an object in my 127.0.0.1:3000 server... Every time I try to fetch, it's a missing session while it's active in the browser....
why would you need to fetch the token?
i thought you are just using next.js backend as the auth guard and trust all conenction to spring boot?
if you still check for auth in the spring boot backend then why use auth0?
I'm still unable to get this thing as an object in my 127.0.0.1:3000 server... Every time I try to fetch, it's a missing session while it's active in the browser....

of course. this make sense. I've explained it to you. your server doesn't have identity while your browser have your identity
if the token is valid then you can access spring boot backend. if it isn't, or return null in the getSession() then it is invalid and would throw error or unauthorized() or something else
whats the token for?
@alfonsüs ardani whats the token for?
Saltwater CrocodileOP
Okay so thus far, this is my understanding of the flow... If what you say is right, I must be wrong somewhere:

1. User clicks login on frontend page defined by nextjs
2. Nextjs redirects to auth0 and auth0 handles login, redirects back to nextjs on a landing page for authenticated users...
3. Every time I make an API call from nextjs, I need to send the access token (I think this is why I need to fetch the token)...
4. Spring boot backend verifies the token using auth0's public keys, and then gives a response or an unauthorised status...
okay so you've architectured your Spring boot backend to also do auth check?
Saltwater CrocodileOP
Separately yes and it works... But not yet as an api to 'this app'
and that's what's confusing me
why not just use client component and directly acces to your spring boot backend from client-side js?
@alfonsüs ardani this is server-side
try getting the result of auth0.getSession()
Answer
what other APIs are available on the auth0 object? perhaps you can get the access token this way
here there is getAccessToken?
@alfonsüs ardani try getting the result of auth0.getSession()
Saltwater CrocodileOP
This is interesting! Yes lemme try this way
...
pls try first before assuming next time
@alfonsüs ardani why not just use client component and directly acces to your spring boot backend from client-side js?
Saltwater CrocodileOP
Trying to fetch from a client component for some reason also gave the same missing session, but yes session object is something interesting...
@alfonsüs ardani pls try first before assuming next time
Saltwater CrocodileOP
Yeah... Idk why I panicked... Thanks man.... A lot