204 lines
6.0 KiB
JavaScript
204 lines
6.0 KiB
JavaScript
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 }; |