NextAuth:在Vercel上未触发会话回调,但在Localhost上触发良好

nszi6y05  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(106)

在localhost上,Google登录工作得很好。但是在将其部署到Vercel时,成功的Google登录后会话总是空的。我查看了Vercel上的日志,我可以看到会话回调从未在Vercel上执行(仅在localhost上执行)
我还在这里创建了issue和vercel url来复制它:https://github.com/nextauthjs/next-auth/issues/9083
[. nextauth].js:

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
    encryption: true,
  },
  debug: true,
  session: {
    // Choose how you want to save the user session.
    // The default is `"jwt"`, an encrypted JWT (JWE) stored in the session cookie.
    // If you use an `adapter` however, we default it to `"database"` instead.
    // You can still force a JWT session by explicitly defining `"jwt"`.
    // When using `"database"`, the session cookie will only contain a `sessionToken` value,
    // which is used to look up the session in the database.
    strategy: "jwt",

    // Seconds - How long until an idle session expires and is no longer valid.
    // 30 days.
    // We need to handle if backend returns error which says that token has expired
    // and then force logout user.
    maxAge: 30 * 24 * 60 * 60,

    // Seconds - Throttle how frequently to write to database to extend a session.
    // Use it to limit write operations. Set to 0 to always update the database.
    // Note: This option is ignored if using JSON Web Tokens
    // updateAge: 24 * 60 * 60, // 24 hours

    // The session token is usually either a random UUID or string, however if you
    // need a more customized session token string, you can define your own generate function.
    // generateSessionToken: () => {
    //   return randomUUID?.() ?? randomBytes(32).toString("hex")
    // }
  },

  callbacks: {
    async jwt({ token, user, account }) {
      // Persist the user.authToken from signIn callback to the token.authToken

      if (account) {
        // Handle the Google ID token here
        const googleIdToken = account.id_token;
        // console.log("nextauth.js jwt: got googleIdToken " + googleIdToken);
        // Send the Google ID token to our backend for verification
        // and exchange it for our backend's token
        // TODO: no way to get locale for now.
        const res = await reqGoogleTokenSignIn(null, googleIdToken);
        const member = res?.data?.data;
        if (member == null) {
          console.log(
            "nextauth.js jwt reqGoogleTokenSignIn: Failed response from be"
          );
          return false;
        }

        console.log(
          "nextauth.js jwt reqGoogleTokenSignIn: Received response from be. authToken: " +
            member.authToken
        );

        let newToken = {};
        newToken.userId = member.id;
        newToken.authToken = member.authToken;
        newToken.profilePictureUrl = member.profilePictureUrl;
        newToken.fullName = member.fullName;
        newToken.emailAddress = member.emailAddress;
        newToken.phoneNumber = member.phoneNumber;

        console.log("nextauth.js jwt: setting token's userId and authToken");
        return newToken;
      }

      return token;
    },

    async session({ session, token }) {
      // Persist the token.authToken from jwt callback to the session.authToken

      console.log(
        "nextauth.js session: setting session's userId and authToken"
      );
      session.userId = token?.userId;
      session.authToken = token?.authToken;
      session.profilePictureUrl = token?.profilePictureUrl;
      session.fullName = token?.fullName;
      session.emailAddress = token?.emailAddress;
      session.phoneNumber = token?.phoneNumber;

      return session;
    },
  },
};
export default NextAuth(authOptions);

字符串
使用session的组件:
LoginBtn.js

function LoginBtn({ provider }) {
  const { data: session, status } = useSession();
  const [loggedIn, setLoggedIn] = useState(null);

  let loginButton = (
    <ImageContainer>
      <OptimizedImage
        onClick={() => signIn("google", { callbackUrl: "/members/profile" })}
        priority={true}
        src="/assets/google-login.png"
        alt={"Login with Google"}
        height={32}
        width={82}
      />
    </ImageContainer>
  );

  let profileButton = (
    <ImageContainer>
      <Link prefetch={false} href={"/members/profile"} legacyBehavior>
        <OptimizedImage
          priority={true}
          src={session?.profilePictureUrl}
          alt={session?.emailAddress + " profile image"}
          height={25}
          width={25}
        />
      </Link>
    </ImageContainer>
  );

  useEffect(() => {
    if (session == null && status === "loading") {
      return;
    } else if (session == null && status === "unauthenticated") {
      setLoggedIn(false);
      return;
    } else if (session != null && status === "authenticated") {
      setLoggedIn(true);
      return;
    }
  }, [session, status]);

  return loggedIn == null ? null : loggedIn ? profileButton : loginButton;
}

export default LoginBtn;


从Vercel的日志:我可以看到这两个日志打印:
nextauth.js jwt reqGoogleTokenSignIn:已收到来自be的响应。authToken:Lcoury0Lfl5MRHfRVs6GY280H144=
nextauth.js jwt:设置token的userId和authToken
但是它缺少会话回调的日志,并且没有错误或任何东西。如果我在localhost上运行它,则会打印此日志。
请告诉我localhost和Vercel部署之间有什么不同?
尝试在vercel env var. ADDED NEXTAUTH_URL上添加NEXTAUTH_SECRET(仍然没有区别),然后将其删除,因为文档表明它们是不必要的
启用nextauth调试模式以查看上述日志

carvr3hs

carvr3hs1#

您是否确保将Google客户端中的回调URL更改为新部署的域?
最好为每个环境创建另一个客户端,以避免每次都手动更改URL。

相关问题