I’ve created a NextJS app and API and have used Auth0 to both manage users and secure the API endpoints. I am only using Email/Password authentication. I had everything working properly but now I am getting the error “AccessTokenError: Could not retrieve an access token with scopes “openid profile email”. The user will need to sign in again.” Signing in again doesn’t work of course. It seems I am only getting a token with the scope “openid” but “profile” and “email” suddenly aren’t available.
The documentation has been a bit confusing but from what I can tell, it seems my Auth0 Application has the necessary scopes available but my Auth0 API does not.
Has anyone run into this error before? I can provide code examples but I am unsure if this is an Auth0 configuration issue or a code issue.
I am not seeing the error in the Auth0 logs. I did have everything working properly and then the access token stopped providing me with the profile and email scopes. Im unsure what changed in that time.
import { initAuth0 } from "@auth0/nextjs-auth0";
export default initAuth0();
I noticed most documentation included a config object in the initAuth0 call, but I was getting an error for every value saying that they were not allowed for some reason.
example: [1] TypeError: "session.cookieSecret" is not allowed
After looking through the source code for this function, I found it is just pulling process.env values, so I just made sure to name my env variables accordingly. Here are the variables I have defined.
I do have those values set for AUTH0_CLIENT_ID , AUTH0_CLIENT_SECRET and AUTH0_ISSUER_BASE_URL but wasn’t sure if I should share them here. And I do have handleAuth() in /pages/api/auth/[...auth0].js. If I’m not mistaken that just exposes the /login /callback and /logout endpoints right?
The JWT being returned doesn’t include the proper scopes. But interestingly enough, I created a stripped-down duplicate of my app, with none of my components, just the login button and user page. And I am seeing the proper scopes represented there. So it must be something that I’m doing in the app that’s causing the issue. I will be adding and removing features to see what causes it.
I am suspecting it’s something to do with my getInitailProps function in certain components that I’m using to pass the AccessToken to my API.
I was finally able to recreate the Could not retrieve an Access Token with scopes... error. It seems to occur when I request a scope that has not been set up for my external API.
However, your env variable is one string with spaces separating each scope. In your code, instead of requesting the “openid”, “profile”, and “email” scopes, the getAccessToken method is looking for one scope called “openid profile email”, which it cannot find.
Your env variable is correct, though. When you decode the JWT, you should see two audiences, for example:
The email, profile, and openid scopes are used for the /userinfo endpoint, not your external API. Since the scopes listed in the getAccessToken method seem to be intended for an external API, I would try removing the scopes optional param:
That seems to have solved it! I also tested this and it worked too: scopes:["openid","profile","email"]. Thank you for clearing that up, I didn’t realize it was looking for one scope when I used that env variable. But it makes sense looking at it now!
I’m still having an issue where routing to a page is resulting in an empty getInitialProps (ie. the catch (err) { block running. Once I refresh everything loads properly though. I’m unsure if that’s Auth0 related or not. I’d assume it means the client side routing is causing an error with auth0.getAccessToken but Im unsure why.
I tried this method, and I am running into one more issue. I am getting a 401 error when I try to access the page that is calling my API. But I can actually access the API endpoint directly in browser and see the data show properly, so I believe I am authenticated properly. When I remove withApiAuthRequired I get a 500 error.
Here’s the getInitialProps of the page that is calling my API
And here’s the API endpoint that is being used as a proxy to call my external API with an access token.
import { getAccessToken, withApiAuthRequired } from "@auth0/nextjs-auth0";
import axios from "axios";
export default withApiAuthRequired(async function getActiveSubscribers(
req,
res
) {
// If your Access Token is expired and you have a Refresh Token
// `getAccessToken` will fetch you a new one using the `refresh_token` grant
const { accessToken } = await getAccessToken(req, res);
const headers = {
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
const customerRes = await axios.get(
"http://localhost:3001/get-active-subscribers",
headers
);
const activeSubscribers = customerRes.data.activeSubscribers;
res.status(200).json(activeSubscribers);
});
Is the request to your API made client-side? Since it is working directly, but not on the webpage, I’m wondering if it might be a CORS issue. If you look at the network requests in dev tools, does it look like an OPTIONS request is failing?