使用 nextjs Auth 获取 OAuthCallbackError

发布于 2025-01-13 07:27:14 字数 5230 浏览 3 评论 0原文

我正在尝试制作一个 Spotify 分析应用程序来分析您的 Spotify 数据。但我在授权时收到此错误。

这是我的身份验证文件。

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;
    },
  },
});

这是我的中间件

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);
  }
}

这是我的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 };

如果有人能在这里帮助我,那就太好了。每次我尝试登录时,都会抛出此错误。(http://localhost:3000/login?callbackUrl=http://localhost:3000/&error=OAuthCallback)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

煮茶煮酒煮时光 2025-01-20 07:27:14

我认为在您的 Spotify 开发人员中会有一个选项(用户和访问权限),您需要通过提供您的电子邮件帐户和他们原来的 Spotify 名称来授予对您帐户的访问权限,仅此而已......

我们不能提供由于 Spotify 开发者选项卡中的限制,无法访问我们 Spotify 应用程序中的所有用户,因此请尝试在开发者仪表板中请求配额延期......这将询问您的应用程序......如果您授予了延期配额,您可以使用任何帐户都可以登录并使用您的 Spotify 应用程序...希望它对您有用你..

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..????

甜味超标? 2025-01-20 07:27:14

在根目录中创建 .env.local 文件并添加如下代码:


    SPOTIFY_CLIENT_ID=YourSPOTIFYClientID
    SPOTIFY_CLIENT_SECRET=SPOTIFYSecretID
    NEXTAUTH_URL=http://localhost:3000
    
    JWT_SECRET=a2H1u5gJEzW7PHRHmxgYaQvxXlNnS1UV

由于 NextAuth 与内置 JSON Web Token(JWT) 保护层配合使用,您可能需要在pages/api/auth/[...nextauth]中定义。 js 文件。查看官方参考此处


    import NextAuth from 'next-auth';
    import SpotifyProvider from 'next-auth/providers/spotify';
    
    export default NextAuth({
    // Configure one or more authentication providers
    providers: [
    SpotifyProvider({
    clientId: process.env.SPOTIFY_CLIENT_ID,
    clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
    }),
    // ...you can add more providers here
    ],
    
    secret: process.env.JWT_SECRET,
    session: {
    strategy: 'jwt',
    },
    });

另外,在 Spotify 开发人员设置的“我的仪表板”中的“编辑设置”中,将重定向 URL 设置为“http://localhost:3000/api/auth/callback/spotify”。
快乐编码!

Create .env.local file in your root directory and add code as below:


    SPOTIFY_CLIENT_ID=YourSPOTIFYClientID
    SPOTIFY_CLIENT_SECRET=SPOTIFYSecretID
    NEXTAUTH_URL=http://localhost:3000
    
    JWT_SECRET=a2H1u5gJEzW7PHRHmxgYaQvxXlNnS1UV

Since, NextAuth works with inbuild JSON Web Token(JWT) protection layer you may need to define in your pages/api/auth/[...nextauth].js file. Check official reference HERE


    import NextAuth from 'next-auth';
    import SpotifyProvider from 'next-auth/providers/spotify';
    
    export default NextAuth({
    // Configure one or more authentication providers
    providers: [
    SpotifyProvider({
    clientId: process.env.SPOTIFY_CLIENT_ID,
    clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
    }),
    // ...you can add more providers here
    ],
    
    secret: process.env.JWT_SECRET,
    session: {
    strategy: 'jwt',
    },
    });

Also, set your redirect URL to "http://localhost:3000/api/auth/callback/spotify" in Edit Settings in My Dashboard from Spotify developer setting.
Happy Coding!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文