Next.js Discord

Discord Forum

Error refreshing access token { error: 'invalid_grant', error_description: 'Refresh token revoked' }

Unanswered
Ocicat posted this in #help-forum
Open in Discord
OcicatOP
I'm having this kind of error when I'm trying to refresh a token using Authjs. I don't know what's the issue.

This is the function that I'm using to refresh.
async function refreshAccessToken(token: any) {
  const response = await fetch("https://accounts.spotify.com/api/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization: `Basic ${Buffer.from(
        `${process.env.AUTH_SPOTIFY_ID}:${process.env.AUTH_SPOTIFY_SECRET}`
      ).toString("base64")}`,
    },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token: token.refresh_token,
    }),
  });
  const refreshedToken = await response.json();
  if (!response.ok) throw refreshedToken;

  console.log("Token refreshed successfully");

  return {
    ...token,
    access_token: refreshedToken.access_token,
    expires_at: Date.now() + refreshedToken.expires_in * 1000,
    refresh_token: refreshedToken.refresh_token || token.refresh_token,
  };
}

8 Replies

OcicatOP
This is where I'm using it:

async jwt({ token, account, user }) {
      if (account) {
        console.log("New authentication, creating new token");
        return {
          ...token,
          access_token: account.access_token,
          expires_at: account.expires_at,
          refresh_token: account.refresh_token,
          user,
        };
      }

      if (token.expires_at && Date.now() < token.expires_at) {
        console.log("Token still valid, returning existing token");
        return token;
      }

      console.log("Token expired, trying to refresh");

      if (!token.refresh_token) {
        throw new Error("Missing refresh token");
      }

      try {
        const refreshedToken = await refreshAccessToken(token);
        console.log("Token refreshed successfully, returning updated token");
        return refreshedToken;
      } catch (error) {
        console.error("Error refreshing access token", error);
        return { ...token, error: "RefreshAccessTokenError" as const };
      }
    },
    session({ session, token }) {
      if (session.user) {
        session.user.id = token.id as string;
        session.access_token = token.access_token as string;
        // added
        session.refresh_token = token.refresh_token as string;
      }

      return session;
    },
  },
Sometimes it works, since I'm getting this:
Token expired, trying to refresh
Token refreshed successfully
Token refreshed successfully, returning updated token
Token still valid, returning existing token


And sometime it doesn't and I'm getting this:
Token expired, trying to refresh
Token refreshed successfully
Token refreshed successfully, returning updated token
Token expired, trying to refresh
Error refreshing access token { error: 'invalid_grant', error_description: 'Refresh token revoked' }
please help, I'm desperate lol
OcicatOP
Anyone?
Korat
Theres an issue with concurrent calls using the old token instead of the new one, you can find some of them in github issues, been trying to make a working auth with next-auth for months now but without success so I stopped and rolled out my own auth.
@Korat Theres an issue with concurrent calls using the old token instead of the new one, you can find some of them in github issues, been trying to make a working auth with next-auth for months now but without success so I stopped and rolled out my own auth.
OcicatOP
so race condition? Thank you, I'll have a look at these tomorrow morning! I need OAuth in my app, so I thought Auth.js would be a fast and good option lol
Korat
Yeah something like that, again not sure how next-auth works under the hood thats why I went with the rolling my own auth option