You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next-Auth OAuth登出后自动登录:需强制重新验证LinkedIn凭证

问题:LinkedIn登录登出后自动重登,需强制每次输入凭证

我在Next.js 14.2.6应用中使用Next-Auth v4.24.11实现LinkedIn登录功能,首次登录正常,但登出后再次尝试登录时,系统会自动完成登录,无需用户输入邮箱和密码。这不符合需求,我希望用户每次登录都需重新输入凭证。


认证路由代码

// src/app/api/auth/[...nextauth]/route.ts

import NextAuth from "next-auth";
import { LinkedInProvider } from "next-auth/providers/linkedin";

const handler = NextAuth({
  providers: [
    LinkedInProvider({
      clientId: process.env.LINKEDIN_CLIENT_ID || "",
      clientSecret: process.env.LINKEDIN_CLIENT_SECRET || "",
      client: { token_endpoint_auth_method: "client_secret_post" },
      issuer: "https://www.linkedin.com",
      profile: (profile: LinkedInProfile) => ({
        id: profile.sub,
        name: profile.name,
        email: profile.email,
        image: profile.picture,
      }),
      wellKnown: "https://www.linkedin.com/oauth/.well-known/openid-configuration",
      authorization: {
        params: {
          scope: "openid profile email",
        },
      },
    }),
  ],
  callbacks: {
    async jwt({ token, account, profile }) {
      if (account) {
        token.accessToken = account.access_token;
      }
      if (profile) {
        token.id = profile.sub;
      }
      return token;
    },
    async session({ session, token }) {
      session.accessToken = token.accessToken as string;
      session.user.id = token.id as string;
      return session;
    },
  },
});

export { handler as GET, handler as POST };

登出按钮代码

const handleLogout = async () => {
    try {
      Cookies.remove("next-auth.session-token");
      Cookies.remove("next-auth.csrf-token");
      Cookies.remove("next-auth.callback-url");
      
      await signOut({ redirect: false });
  
      Cookies.remove("isLogged");
      Cookies.remove("userId");
      localStorage.removeItem("profile_pic");
      sessionStorage.clear();
  
      router.push("/login");
    } catch (error) {
      console.error("Error during logout:", error);
    }
  };

登录按钮代码

<button
    className="linkedin-button flex items-center justify-center w-full py-2 bg-white border rounded-full shadow-md hover:bg-gray-100"
    onClick={() => signIn("linkedin")}
  >
    <Image
      src="/linkedin.webp"
      alt="Logo"
      width={28}
      height={28}
      priority
      className="mr-2"
    />
    Login with LinkedIn
  </button>

当前问题现象

登出后会话未正确清除,虽然登出响应显示session {},但next-auth.csrf-token和next-auth.callback-url Cookie仍存在,登出的set-cookie头为:

set-cookie: next-auth.callback-url=http%3A%2F%2Flocalhost%3A3000%2Fdashboard%3Fmessage%3Dsuccess; Path=/; HttpOnly; SameSite=Lax

已尝试的方法

  • signOut({ redirect: false, callbackUrl: '/' });
  • 在登录按钮中添加prompt:login参数,但问题仍未解决。

解决方案

1. 强制LinkedIn重新认证,添加授权参数

问题核心是LinkedIn端保留了用户会话,导致自动跳过登录步骤。需要在LinkedInProvider的授权配置中添加prompt: "login",强制每次登录都要求用户输入凭证:

修改认证路由中的LinkedInProvider配置:

LinkedInProvider({
  // ...其他原有配置
  authorization: {
    params: {
      scope: "openid profile email",
      prompt: "login" // 新增此行,强制用户重新验证身份
    },
  },
}),

2. 优化登出流程,避免手动清除Cookie冲突

不要手动删除Next-Auth的内置Cookie,signOut方法会自动处理这些Cookie的清除逻辑。手动删除会和signOut的内置流程冲突,导致部分Cookie被重新设置。

修改登出按钮代码:

const handleLogout = async () => {
  try {
    // 先调用signOut,让Next-Auth处理自身Cookie
    await signOut({ 
      redirect: false,
      callbackUrl: "/login" // 指定登出后跳转地址,避免错误设置callback-url
    });

    // 再清除自定义的Cookie和本地存储
    Cookies.remove("isLogged");
    Cookies.remove("userId");
    localStorage.removeItem("profile_pic");
    sessionStorage.clear();

    router.push("/login");
  } catch (error) {
    console.error("Error during logout:", error);
  }
};

3. 验证登出后的Cookie状态

执行登出后,检查浏览器Cookie:

  • 确认next-auth.session-token已被清除
  • next-auth.callback-url应被设置为指定的/login,而非之前的dashboard地址

说明:这不是Next-Auth的Bug

这是OAuth2认证流程的正常现象:LinkedIn作为授权服务器,会在用户浏览器保留自身会话Cookie,导致再次授权时自动跳过登录步骤。添加prompt: "login"是强制授权服务器重新验证用户身份的标准方式。

内容的提问来源于stack exchange,提问作者JISHNU T RAJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:39:55