Skip to content
Advertisement

Getting OAuthCallbackError with nextjs Auth

I am trying to make a spotify analysis app that would analyse your Spotify data. But I am getting this error on authorization.

Here is my auth file.

import NextAuth from "next-auth";
import SpotifyProvider from "next-auth/providers/spotify";
import spotifyApi, { LOGIN_URL } from "../../../lib/spotify";

async function refreshAccessToken(token) {
  try {
    spotifyApi.setAccessToken(token.accessToken);
    spotifyApi.setRefreshToken(token.refreshToken);

    const { body: refreshedToken } = await spotifyApi.refreshAccessToken();
    console.log("Refreshed token is", refreshedToken);

    return {
      ...token,
      accessToken: refreshedToken.access_token,
      accessTokenExpires: Date.now() + refreshedToken.expires_in * 1000,
      refreshToken: refreshedToken.refresh_token ?? token.refreshToken,
    };
  } catch (error) {
    console.log(error);

    return {
      ...token,
      error: "RefreshAccessTokenError",
    };
  }
}

export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    SpotifyProvider({
      clientId: process.env.NEXT_PUBLIC_CLIENT_ID,
      clientSecret: process.env.NEXT_PUBLIC_CLIENT_SECRET,
      authorization: LOGIN_URL,
    }),
    // ...add more providers here
  ],
  secret: process.env.JWT_SECRET,
  pages: {
    signIn: "/login",
  },
  callbacks: {
    async jwt({ token, account, user }) {
      //initial Signin
      if (account && user) {
        return {
          ...token,
          accessToken: account.access_token,
          refreshToken: account.refresh_token,
          username: account.providerAccountId,
          accessTokenExpires: account.expires_at * 1000,
        };
      }

      //Return previous token if the access token has not expired
      if (Date.now() < token.accessTokenExpires) {
        console.log("Existing Access Token is valid");
        return token;
      }

      //Access token expired, time to refresh it
      console.log("Existing Access Token has expired, Refreshing...");
      return await refreshAccessToken(token);
    },

    async session({ session, token }) {
      session.user.accessToken = token.accessToken;
      session.user.refreshToken = token.refreshToken;
      session.user.username = token.username;

      return session;
    },
  },
});

this is my middleware

import { getToken } from "next-auth/jwt";
import { NextResponse } from "next/server";

export async function middleware(req) {
  //token will exist if user is logged in
  const token = await getToken({ req, secret: process.env.JWT_SECRET });

  const { pathname } = req.nextUrl;

  // Allow the request if the following is true...
  // 1) It's a request for next-auth session and provider fetching
  // 2) the token exists
  if (pathname.includes("/api/auth") || token) {
    return NextResponse.next();
  }
  if (!token && pathname !== "/login") {
    const url = req.nextUrl.clone();
    url.pathname = "/login";
    return NextResponse.rewrite(url);
  }
}

this is my login.js

import { getProviders, signIn } from "next-auth/react";
import { signOut, useSession } from "next-auth/react";

function login({ providers }) {
  return (
    <div className="flex bg-[#ffcdd2] min-h-screen">
      <div>
        <img
          className="w-12 h-12 m-2 fill-blue-500"
          src="https://links.papareact.com/9xl"
          alt="spotify"
        />
      </div>
      <div className="flex flex-col items-center justify-center ml-[35rem]">
        <h1 className="font-mono text-[70px]">Spotivy</h1>
        {Object.values(providers).map((provider) => (
          <div key={provider.id}>
            <button
              className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full mt-4"
              onClick={() => signIn(provider.id, { callbackUrl: "/" })}
            >
              Login with {provider.name}
            </button>
          </div>
        ))}
        <button onClick={() => signOut()}>Sign Out</button>
      </div>
    </div>
  );
}

export default login;

export async function getServerSideProps() {
  const providers = await getProviders();

  return {
    props: {
      providers,
    },
  };
}

import SpotifyWebApi from "spotify-web-api-node";

const scopes = [
  "user-read-email",
  "playlist-read-private",
  "playlist-read-collaborative",
  "user-read-email",
  "streaming",
  "user-read-private",
  "user-library-read",
  "user-top-read",
  "user-read-playback-state",
  "user-modify-playback-state",
  "user-read-currently-playing",
  "user-read-recently-played",
  "user-follow-read",
].join(",");

const params = {
  scope: scopes,
};

const queryParamString = new URLSearchParams(params);

const LOGIN_URL =
  "https://accounts.spotify.com/authorize?" + queryParamString.toString();

const spotifyApi = new SpotifyWebApi({
  clientId: process.env.NEXT_PUBLIC_CLIENT_ID,
  clientSecret: process.env.NEXT_PUBLIC_CLIENT_SECRET,
});

export default spotifyApi;

export { LOGIN_URL };

It would be really great if someone could help me out here. Everytime I am trying to login,it’s throwing me this error.(http://localhost:3000/login?callbackUrl=http://localhost:3000/&error=OAuthCallback)

Advertisement

Answer

I think in your Spotify Developer there will be an option(users and access) there you need to give access to your account by just giving your email account I’d and their original Spotify name that’s it ……

We cannot give access to all users in our Spotify App due to limitations in Spotify developers tab so try to request for quota extension in the developers dashboard…. Which will ask about your app…. If you granted with an extension quota you can use any accounts to login and use your Spotify app…. Hope it will be useful to you..😊

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement