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

Netlify部署下Next Auth 5.0.0-beta.18会话无法清除问题

NextAuth v5.0.0-beta.18 Netlify部署后登出会话未清除问题

我使用NextAuth v5.0.0-beta.18的Credentials Provider实现认证功能,将应用部署到Netlify后出现异常:执行登出操作后刷新页面,用户会话并未被清除,但该功能在本地开发环境和Vercel部署环境下均正常工作。

相关配置与代码

auth.ts(NextAuth核心配置)

export const { handlers, signIn, signOut, auth } = NextAuth({
    providers: [
        Credentials({
            id: "credentials",
            name: "credentials",
            credentials: {
                email: {
                    label: "Email"
                },
                password: {
                    label: "Password",
                    type: "password"
                }
            },
            async authorize(credentials) {
                const { response, error } = await withAsync(() => signInWithCredentials({
                    email: credentials.email as string,
                    password: credentials.password as string
                }));

                if (error) {
                    if (isApiError(error)) {
                        return null;
                    } else {
                        throw new Error("An unexpected issue occurred.");
                    }
                }

                return {
                    ...response
                };
            },
        }),
        Credentials({
            id: "register",
            name: "register",
            async authorize(credentials) {
                console.log("credentials: ", credentials);
                
                const response = JSON.parse(JSON.stringify(credentials));
                const user = removePrefixFromObjectKeys(response, "userpre_")
                const metadata = removePrefixFromObjectKeys(response, "metadatapre_")
                user.metadata = metadata;

                return {
                    ...response,
                    user
                }
            },
        })
    ],
    callbacks: {
        jwt({ token, user }) {
            if (user) return { ...token, ...user }

            return token;
        },
        session(params) {
            const { session, token } = params;
            // @ts-ignore
            session.user = token;

            return session;
        },
    },
    pages: {
        signIn: "/signin",
        newUser: "/",
    },
    secret: process.env.AUTH_SECRET,
    trustHost: true,
})

导航栏组件(调用登出操作)

export function NavAction() {
    return (
        <div className="flex items-center gap-4">
            <Button variant="fatal">
                <HiOutlineGift className="h-4 w-4 mr-2" />
                Your entries: 53
            </Button>

            <DropdownMenu>
                <DropdownMenuTrigger asChild>
                    <button>
                        <HiUserCircle className="h-12 w-12" />
                    </button>
                </DropdownMenuTrigger>
                <DropdownMenuContent className="w-20 z-[9999]">
                    <DropdownMenuItem onClick={async () => {
                        await authSignOut()
                    }}>
                        <HiMiniArrowRightOnRectangle className="mr-2 h-4 w-4" />
                        <span>Log out</span>
                    </DropdownMenuItem>
                </DropdownMenuContent>
            </DropdownMenu>
        </div>
    )
}

action.ts(服务端认证操作)

"use server";

import { signOut, signIn } from "@/auth";
import { AuthError } from "next-auth";

function isRedirectError(error: Error & { digest?: string }) {
    return !!error.digest?.startsWith("NEXT_REDIRECT")
}

export async function authSignOut() {
    // await signOut({
    //     redirect: false
    // });
    await signOut();
}

export async function authSignIn(prevState: any, data: FormData) {
    try {
        await signIn('credentials', data);

        return {
            status: 'success',
            error: ''
        }
    } catch (error) {
        if (isRedirectError(error as Error)) {
            return {
                status: 'success',
                error: ''
            }
        };

        if (error instanceof AuthError) {
            switch (error.type) {
                case 'CredentialsSignin':
                    return {
                        status: 'failed',
                        error: 'Invalid email or password.'
                    };
                default:
                    return {
                        status: 'failed',
                        error: 'Something went wrong.'
                    };
            }
        }

        throw error;
    }
}

export async function authRegisterSigIn(data: FormData) {
    await signIn("register", data);
}

内容的提问来源于stack exchange,提问作者Ameer Hamza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 15:30:19