110 lines
4.5 KiB
JavaScript
110 lines
4.5 KiB
JavaScript
const { PrismaClient } = require('@prisma/client');
|
||
|
||
async function checkNextAuthSessions() {
|
||
const prisma = new PrismaClient();
|
||
|
||
try {
|
||
console.log('=== NextAuth.js 会话状态检查 ===\n');
|
||
|
||
// 1. 检查 JWT 配置
|
||
console.log('1. JWT/Session 配置检查:');
|
||
console.log(' NEXTAUTH_SECRET:', process.env.NEXTAUTH_SECRET ? '已设置' : '未设置');
|
||
console.log(' NEXTAUTH_URL:', process.env.NEXTAUTH_URL || '未设置');
|
||
|
||
// 2. 创建一个测试 JWT token 来验证签名
|
||
console.log('\n2. JWT Token 验证测试:');
|
||
const testPayload = {
|
||
email: 'test@example.com',
|
||
name: 'Test User',
|
||
id: 'test-id',
|
||
role: 'ADMIN',
|
||
isSuperAdmin: true,
|
||
iat: Math.floor(Date.now() / 1000),
|
||
exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 7) // 7天过期
|
||
};
|
||
|
||
if (process.env.NEXTAUTH_SECRET) {
|
||
try {
|
||
const testToken = jwt.sign(testPayload, process.env.NEXTAUTH_SECRET);
|
||
console.log(' JWT Token 创建成功');
|
||
console.log(' Token 长度:', testToken.length);
|
||
|
||
// 验证 token
|
||
const decoded = jwt.verify(testToken, process.env.NEXTAUTH_SECRET);
|
||
console.log(' JWT Token 验证成功');
|
||
console.log(' 解码结果:', {
|
||
email: decoded.email,
|
||
role: decoded.role,
|
||
isSuperAdmin: decoded.isSuperAdmin,
|
||
exp: new Date(decoded.exp * 1000).toISOString()
|
||
});
|
||
} catch (error) {
|
||
console.log(' JWT Token 创建/验证失败:', error.message);
|
||
}
|
||
} else {
|
||
console.log(' 无法创建测试 token:NEXTAUTH_SECRET 未设置');
|
||
}
|
||
|
||
// 3. 检查中间件逻辑
|
||
console.log('\n3. 中间件认证流程模拟:');
|
||
console.log(' 用户尝试访问 / 路径');
|
||
console.log(' 中间件检查逻辑:');
|
||
console.log(' 1. 调用 getToken() 获取 JWT token');
|
||
console.log(' 2. 如果没有 token,重定向到 /login');
|
||
console.log(' 3. 如果有 token,检查 token.role');
|
||
console.log(' 4. 如果是管理员才能访问 /admin 路径');
|
||
|
||
// 4. 模拟空数据库场景下的认证行为
|
||
console.log('\n4. 当前数据库状态分析:');
|
||
console.log(' ✅ 数据库连接正常');
|
||
console.log(' ❌ 用户表为空 (0个用户)');
|
||
console.log(' ✅ 系统设置正常');
|
||
console.log(' ✅ 目标用户不存在');
|
||
|
||
// 5. 可能的问题分析
|
||
console.log('\n5. 问题根源分析:');
|
||
console.log(' 🔍 可能原因:');
|
||
console.log(' - 浏览器保存了旧的 JWT token');
|
||
console.log(' - NextAuth.js 默认允许未验证的会话');
|
||
console.log(' - 中间件在 token 验证失败时没有正确处理');
|
||
console.log(' - 应用可能有多个运行实例连接不同数据库');
|
||
|
||
// 6. 解决方案建议
|
||
console.log('\n6. 解决方案建议:');
|
||
console.log(' 🎯 立即解决方案:');
|
||
console.log(' 1. 清理浏览器数据:');
|
||
console.log(' - LocalStorage 中的 next-auth.* 条目');
|
||
console.log(' - SessionStorage 中的认证相关数据');
|
||
console.log(' - Cookies 中的 next-auth.* 条目');
|
||
console.log(' 2. 使用无痕/隐私模式重新测试登录');
|
||
console.log(' 3. 强制清除 NextAuth.js 会话状态');
|
||
|
||
console.log('\n 🛠️ 代码层面解决方案:');
|
||
console.log(' - 在中间件中添加更严格的 token 验证');
|
||
console.log(' - 在认证回调中验证数据库中用户是否仍然存在');
|
||
console.log(' - 添加会话自动失效逻辑');
|
||
|
||
// 7. 创建会话清理脚本
|
||
console.log('\n7. 会话清理建议:');
|
||
console.log(' 用户可以在浏览器控制台执行:');
|
||
console.log(' ```javascript');
|
||
console.log(' // 清理 NextAuth.js 数据');
|
||
console.log(' localStorage.removeItem("next-auth.session-token")');
|
||
console.log(' localStorage.removeItem("next-auth.callback-url")');
|
||
console.log(' localStorage.removeItem("next-auth.csrf-token")');
|
||
console.log(' sessionStorage.clear();');
|
||
console.log(' // 或者强制刷新页面');
|
||
console.log(' location.reload(true);');
|
||
console.log(' ```');
|
||
|
||
console.log('\n=== 检查完成 ===');
|
||
console.log('💡 建议:先尝试清理浏览器缓存,如果问题仍然存在,检查是否有多实例部署');
|
||
|
||
} catch (error) {
|
||
console.error('检查过程中出现错误:', error);
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|
||
|
||
checkNextAuthSessions(); |