Files
pdnode-account/test-redirect-uri.js
2025-07-29 17:31:14 -07:00

204 lines
6.0 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 axios = require('axios');
// 测试重定向URI匹配逻辑
function testRedirectUriMatching() {
console.log('🧪 测试重定向URI匹配逻辑...\n');
// 模拟数据库中存储的URI
const storedUris = [
'http://localhost:3001/third-party-app.html',
'http://localhost:3001/callback',
'https://example.com/callback'
];
// 测试用例
const testCases = [
{
requested: 'http://127.0.0.1:5500/public/third-party-app.html',
expected: true,
description: '不同主机名和端口,相同路径'
},
{
requested: 'http://localhost:3001/third-party-app.html',
expected: true,
description: '完全匹配'
},
{
requested: 'http://localhost:3001/callback',
expected: true,
description: '匹配callback路径'
},
{
requested: 'http://127.0.0.1:8080/callback',
expected: true,
description: '不同端口,相同路径'
},
{
requested: 'http://localhost:3001/different-path.html',
expected: false,
description: '路径不匹配'
},
{
requested: 'https://localhost:3001/third-party-app.html',
expected: false,
description: '协议不匹配'
}
];
// 验证函数(与后端逻辑相同)
const isValidRedirectUri = (storedUris, requestedUri) => {
try {
const requestedUrl = new URL(requestedUri);
for (const storedUri of storedUris) {
const storedUrl = new URL(storedUri);
// 检查协议是否匹配
if (requestedUrl.protocol !== storedUrl.protocol) {
continue;
}
// 获取文件名(路径的最后一部分)
const requestedFilename = requestedUrl.pathname.split('/').pop();
const storedFilename = storedUrl.pathname.split('/').pop();
// 检查文件名是否匹配,忽略路径前缀
if (requestedFilename === storedFilename) {
return true;
}
// 如果文件名不匹配,检查完整路径是否匹配
if (requestedUrl.pathname === storedUrl.pathname) {
return true;
}
}
return false;
} catch (error) {
return false;
}
};
// 运行测试
let passed = 0;
let total = testCases.length;
testCases.forEach((testCase, index) => {
const result = isValidRedirectUri(storedUris, testCase.requested);
const status = result === testCase.expected ? '✅' : '❌';
console.log(`${status} 测试 ${index + 1}: ${testCase.description}`);
console.log(` 请求URI: ${testCase.requested}`);
console.log(` 期望结果: ${testCase.expected}, 实际结果: ${result}`);
console.log('');
if (result === testCase.expected) {
passed++;
}
});
console.log(`📊 测试结果: ${passed}/${total} 通过`);
if (passed === total) {
console.log('🎉 所有测试通过重定向URI验证逻辑正常工作。');
} else {
console.log('⚠️ 部分测试失败,需要检查逻辑。');
}
}
// 测试实际的OAuth流程
async function testOAuthFlow() {
console.log('\n🚀 测试实际OAuth流程...\n');
try {
// 1. 注册用户
const testUser = {
username: `testuser_${Date.now()}`,
email: `testuser_${Date.now()}@example.com`,
password: 'TestPassword123'
};
console.log('1. 注册测试用户...');
const registerResponse = await axios.post('http://localhost:3000/api/auth/register', testUser);
if (!registerResponse.data.success) {
console.log('❌ 用户注册失败:', registerResponse.data.message);
return;
}
console.log('✅ 用户注册成功');
// 2. 用户登录
console.log('\n2. 用户登录...');
const loginResponse = await axios.post('http://localhost:3000/api/auth/login', {
username: testUser.username,
password: testUser.password
});
if (!loginResponse.data.success) {
console.log('❌ 用户登录失败:', loginResponse.data.message);
return;
}
const userToken = loginResponse.data.data.token;
console.log('✅ 用户登录成功');
// 3. 创建OAuth客户端
console.log('\n3. 创建OAuth客户端...');
const clientData = {
name: '测试应用',
description: '测试重定向URI匹配',
redirect_uris: ['http://localhost:3001/third-party-app.html']
};
const clientResponse = await axios.post('http://localhost:3000/api/oauth/clients', clientData, {
headers: {
'Authorization': `Bearer ${userToken}`
}
});
if (!clientResponse.data.success) {
console.log('❌ OAuth客户端创建失败:', clientResponse.data.message);
return;
}
const clientId = clientResponse.data.data.client_id;
console.log('✅ OAuth客户端创建成功');
console.log(` 客户端ID: ${clientId}`);
// 4. 测试授权请求
console.log('\n4. 测试授权请求...');
const authParams = new URLSearchParams({
response_type: 'code',
client_id: clientId,
redirect_uri: 'http://127.0.0.1:5500/public/third-party-app.html',
scope: 'read write',
state: 'test123'
});
const authResponse = await axios.get(`http://localhost:3000/api/oauth/authorize?${authParams}`, {
headers: {
'Authorization': `Bearer ${userToken}`
}
});
if (authResponse.data.success) {
console.log('✅ 授权请求成功!');
console.log(` 应用名称: ${authResponse.data.data.client.name}`);
console.log(` 请求权限: ${authResponse.data.data.scopes.join(', ')}`);
} else {
console.log('❌ 授权请求失败:', authResponse.data.message);
if (authResponse.data.debug) {
console.log(' 调试信息:', authResponse.data.debug);
}
}
} catch (error) {
console.error('❌ 测试过程中发生错误:', error.response?.data || error.message);
}
}
// 运行测试
if (require.main === module) {
testRedirectUriMatching();
testOAuthFlow();
}
module.exports = { testRedirectUriMatching, testOAuthFlow };