Enhance authentication and debugging experience by adding detailed logging for cookie checks, session management, and user redirection. Update middleware to log authentication cookie status and user login state. Refactor login and debug pages to use hard redirects for improved reliability and include session data display. Implement custom cookie handling in Supabase client for better session management.
This commit is contained in:
@@ -7,8 +7,11 @@ export async function GET(request: NextRequest) {
|
||||
const requestUrl = new URL(request.url);
|
||||
const code = requestUrl.searchParams.get('code');
|
||||
|
||||
console.log('Auth callback received:', { url: request.url, hasCode: !!code });
|
||||
|
||||
// 如果没有code参数,则重定向到登录页面
|
||||
if (!code) {
|
||||
console.log('没有找到code参数,重定向到登录页面');
|
||||
return NextResponse.redirect(new URL('/login', request.url));
|
||||
}
|
||||
|
||||
@@ -18,9 +21,42 @@ export async function GET(request: NextRequest) {
|
||||
const supabaseRouteHandler = createRouteHandlerClient({ cookies: () => cookieStore });
|
||||
|
||||
// 交换code获取会话
|
||||
await supabaseRouteHandler.auth.exchangeCodeForSession(code);
|
||||
console.log('开始交换code获取会话');
|
||||
const { data, error } = await supabaseRouteHandler.auth.exchangeCodeForSession(code);
|
||||
|
||||
// 直接重定向到首页,避免中间跳转
|
||||
if (error) {
|
||||
console.error('交换会话时出错:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('成功获取会话,用户:', data.session?.user.email);
|
||||
|
||||
// 检查会话是否成功创建
|
||||
if (data.session) {
|
||||
console.log('会话创建成功:', {
|
||||
userId: data.session.user.id,
|
||||
email: data.session.user.email,
|
||||
expiresAt: data.session.expires_at ? new Date(data.session.expires_at * 1000).toISOString() : 'unknown'
|
||||
});
|
||||
|
||||
// 设置额外的cookie以确保客户端能检测到登录状态
|
||||
// 使用Next.js的Response来设置cookie
|
||||
const response = NextResponse.redirect(new URL('/', request.url));
|
||||
response.cookies.set({
|
||||
name: 'sb-auth-token',
|
||||
value: 'true',
|
||||
path: '/',
|
||||
maxAge: 60 * 60 * 24 * 7, // 7 days
|
||||
sameSite: 'lax',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
httpOnly: false,
|
||||
});
|
||||
console.log('设置了备用cookie: sb-auth-token');
|
||||
return response;
|
||||
}
|
||||
|
||||
// 优先使用应用程序根路径重定向
|
||||
console.log('重定向到首页');
|
||||
return NextResponse.redirect(new URL('/', request.url));
|
||||
} catch (error) {
|
||||
console.error('Auth callback error:', error);
|
||||
|
||||
@@ -8,6 +8,8 @@ export default function DebugPage() {
|
||||
const { user, session, isLoading } = useAuth();
|
||||
const [cookies, setCookies] = useState<Record<string, string>>({});
|
||||
const [rawCookies, setRawCookies] = useState('');
|
||||
const [sessionData, setSessionData] = useState<{ session: any; user: any } | null>(null);
|
||||
const [redirectTarget, setRedirectTarget] = useState('/analytics');
|
||||
|
||||
useEffect(() => {
|
||||
// 获取所有cookie
|
||||
@@ -22,14 +24,46 @@ export default function DebugPage() {
|
||||
|
||||
// 测试supabase会话
|
||||
const testSession = async () => {
|
||||
const { data, error } = await supabase.auth.getSession();
|
||||
console.log('Debug page - Supabase session:', data);
|
||||
if (error) console.error('Debug page - Session error:', error);
|
||||
try {
|
||||
console.log('正在获取Supabase会话');
|
||||
const { data, error } = await supabase.auth.getSession();
|
||||
console.log('Supabase session result:', { data, error });
|
||||
|
||||
if (error) {
|
||||
console.error('Session error:', error);
|
||||
} else {
|
||||
setSessionData(data);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取会话出错:', err);
|
||||
}
|
||||
};
|
||||
|
||||
testSession();
|
||||
}, []);
|
||||
|
||||
const refreshSession = async () => {
|
||||
try {
|
||||
console.log('手动刷新会话');
|
||||
const { data, error } = await supabase.auth.refreshSession();
|
||||
console.log('刷新结果:', { data, error });
|
||||
alert('会话刷新完成,请查看控制台日志');
|
||||
|
||||
if (!error && data.session) {
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('刷新会话出错:', err);
|
||||
alert('刷新会话出错: ' + String(err));
|
||||
}
|
||||
};
|
||||
|
||||
const forceRedirect = () => {
|
||||
if (redirectTarget) {
|
||||
window.location.href = redirectTarget;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-8">
|
||||
<h1 className="text-3xl font-bold mb-6">认证调试页面</h1>
|
||||
@@ -42,9 +76,24 @@ export default function DebugPage() {
|
||||
<p>用户邮箱: {user?.email || '未登录'}</p>
|
||||
<p>用户ID: {user?.id || '未登录'}</p>
|
||||
<p>会话有效: {session ? '是' : '否'}</p>
|
||||
<p>会话过期时间: {session?.expires_at ? new Date(session.expires_at * 1000).toLocaleString() : '无会话'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-100 p-6 rounded-lg mb-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Supabase 会话数据</h2>
|
||||
<pre className="bg-gray-200 p-4 rounded text-xs overflow-auto max-h-60">
|
||||
{sessionData ? JSON.stringify(sessionData, null, 2) : '加载中...'}
|
||||
</pre>
|
||||
|
||||
<button
|
||||
onClick={refreshSession}
|
||||
className="mt-4 px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
|
||||
>
|
||||
刷新会话
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-100 p-6 rounded-lg mb-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Cookies 信息</h2>
|
||||
<div className="space-y-2">
|
||||
@@ -67,6 +116,25 @@ export default function DebugPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-100 p-6 rounded-lg mb-6">
|
||||
<h2 className="text-xl font-semibold mb-4">手动重定向</h2>
|
||||
<div className="flex space-x-2 items-center">
|
||||
<input
|
||||
type="text"
|
||||
value={redirectTarget}
|
||||
onChange={(e) => setRedirectTarget(e.target.value)}
|
||||
className="flex-1 px-3 py-2 border border-gray-300 rounded"
|
||||
placeholder="/analytics"
|
||||
/>
|
||||
<button
|
||||
onClick={forceRedirect}
|
||||
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
||||
>
|
||||
强制重定向
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => window.location.href = '/login'}
|
||||
@@ -76,8 +144,13 @@ export default function DebugPage() {
|
||||
</button>
|
||||
<button
|
||||
onClick={async () => {
|
||||
await supabase.auth.signOut();
|
||||
window.location.reload();
|
||||
try {
|
||||
await supabase.auth.signOut();
|
||||
alert('已登出,刷新页面中...');
|
||||
window.location.reload();
|
||||
} catch (err) {
|
||||
alert('登出出错: ' + String(err));
|
||||
}
|
||||
}}
|
||||
className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, Suspense } from 'react';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { useAuth } from '@/lib/auth';
|
||||
|
||||
@@ -20,7 +20,6 @@ function MessageHandler({ setMessage }: { setMessage: (message: { type: string,
|
||||
}
|
||||
|
||||
export default function LoginPage() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const { signIn, signInWithGoogle, user } = useAuth();
|
||||
|
||||
@@ -43,13 +42,21 @@ export default function LoginPage() {
|
||||
// 如果用户已登录,重定向到原始页面或首页
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
if (redirectUrl) {
|
||||
router.push(redirectUrl);
|
||||
} else {
|
||||
router.push('/');
|
||||
}
|
||||
console.log('用户已登录,准备重定向', { redirectUrl });
|
||||
|
||||
// 添加短暂延时确保状态更新完成
|
||||
setTimeout(() => {
|
||||
if (redirectUrl) {
|
||||
// 使用硬重定向替代router.push
|
||||
console.log('重定向到原始URL:', redirectUrl);
|
||||
window.location.href = redirectUrl;
|
||||
} else {
|
||||
console.log('重定向到首页');
|
||||
window.location.href = '/';
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}, [user, router, redirectUrl]);
|
||||
}, [user, redirectUrl]);
|
||||
|
||||
const handleEmailSignIn = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
23
app/page.tsx
23
app/page.tsx
@@ -1,31 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAuth } from '@/lib/auth';
|
||||
|
||||
export default function Home() {
|
||||
const router = useRouter();
|
||||
const { user, isLoading } = useAuth();
|
||||
|
||||
// 添加调试日志
|
||||
console.log('根页面状态:', { isLoading, userAuthenticated: !!user });
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading) {
|
||||
console.log('准备从根页面重定向', { isLoggedIn: !!user });
|
||||
|
||||
// 使用硬重定向确保页面完全刷新
|
||||
if (user) {
|
||||
// 已登录用户重定向到分析页面
|
||||
router.push('/analytics');
|
||||
console.log('用户已登录,重定向到分析页面');
|
||||
window.location.href = '/analytics';
|
||||
} else {
|
||||
// 未登录用户重定向到登录页面
|
||||
router.push('/login');
|
||||
console.log('用户未登录,重定向到登录页面');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
}
|
||||
}, [user, isLoading, router]);
|
||||
}, [isLoading, user]);
|
||||
|
||||
// 显示加载指示器
|
||||
// 显示加载指示器,并包含状态信息
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500 mx-auto"></div>
|
||||
<p className="mt-4 text-lg text-gray-700">正在加载...</p>
|
||||
<p className="mt-2 text-sm text-gray-500">
|
||||
状态: {isLoading ? '检查登录中' : (user ? '已登录' : '未登录')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user