flnxi-Wu/scripts/tools/check_nextauth_sessions.js
WuYongJie f646b71813
Some checks failed
CI Check / check (push) Has been cancelled
chore: 初始化本地仓库并同步最近改动
2025-11-18 17:50:16 +08:00

110 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();