oidc-gateway-demo/resourceservicehtml/test.html

202 lines
7.6 KiB
HTML
Raw Permalink Normal View History

2025-07-18 14:28:47 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>OIDC配置测试</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.test-section {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.success { background-color: #d4edda; color: #155724; border-color: #c3e6cb; }
.error { background-color: #f8d7da; color: #721c24; border-color: #f5c6cb; }
button {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
margin: 5px;
}
button:hover { background-color: #0056b3; }
pre {
background-color: #f8f9fa;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>OIDC配置测试</h1>
<div class="test-section">
<h3>1. 当前配置</h3>
<pre id="config"></pre>
</div>
<div class="test-section">
<h3>2. 测试OIDC端点</h3>
<button onclick="testOidcEndpoints()">测试OIDC端点</button>
<div id="endpointResults"></div>
</div>
<div class="test-section">
<h3>3. 测试登录流程</h3>
<button onclick="testLoginFlow()">测试登录流程</button>
<div id="loginResults"></div>
</div>
<div class="test-section">
<h3>4. 当前Token状态</h3>
<button onclick="checkTokenStatus()">检查Token状态</button>
<div id="tokenResults"></div>
</div>
</div>
<script>
// OIDC配置
const oidcConfig = {
clientId: 'a-client',
clientSecret: 'a-secret',
2025-07-18 16:11:31 +08:00
redirectUri: 'https://a.local.com/callback',
authorizationEndpoint: 'https://oidc.local.com/oauth2/authorize',
tokenEndpoint: 'https://oidc.local.com/oauth2/token',
userInfoEndpoint: 'https://oidc.local.com/userinfo',
jwksEndpoint: 'https://oidc.local.com/oauth2/jwks',
2025-07-18 14:28:47 +08:00
scope: 'openid read'
};
// 显示配置
document.getElementById('config').textContent = JSON.stringify(oidcConfig, null, 2);
// 测试OIDC端点
async function testOidcEndpoints() {
const results = document.getElementById('endpointResults');
results.innerHTML = '<p>正在测试端点...</p>';
const tests = [
{ name: 'JWKS端点', url: oidcConfig.jwksEndpoint },
{ name: '授权端点', url: oidcConfig.authorizationEndpoint },
{ name: 'Token端点', url: oidcConfig.tokenEndpoint },
{ name: '用户信息端点', url: oidcConfig.userInfoEndpoint }
];
let resultsHtml = '';
for (const test of tests) {
try {
const response = await fetch(test.url, { method: 'GET' });
const status = response.status;
const statusText = response.statusText;
if (status === 200 || status === 401) {
resultsHtml += `<p class="success">✅ ${test.name}: ${status} ${statusText}</p>`;
} else {
resultsHtml += `<p class="error">❌ ${test.name}: ${status} ${statusText}</p>`;
}
} catch (error) {
resultsHtml += `<p class="error">❌ ${test.name}: 连接失败 - ${error.message}</p>`;
}
}
results.innerHTML = resultsHtml;
}
// 测试登录流程
function testLoginFlow() {
const results = document.getElementById('loginResults');
results.innerHTML = '<p>正在生成登录URL...</p>';
const state = generateRandomString();
localStorage.setItem('oauth_state', state);
const authUrl = new URL(oidcConfig.authorizationEndpoint);
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', oidcConfig.clientId);
authUrl.searchParams.set('redirect_uri', oidcConfig.redirectUri);
authUrl.searchParams.set('scope', oidcConfig.scope);
authUrl.searchParams.set('state', state);
results.innerHTML = `
<p class="success">✅ 登录URL已生成</p>
<p><strong>State:</strong> ${state}</p>
<p><strong>授权URL:</strong></p>
<pre>${authUrl.toString()}</pre>
<button onclick="window.open('${authUrl.toString()}', '_blank')">在新窗口打开登录</button>
`;
}
// 检查Token状态
function checkTokenStatus() {
const results = document.getElementById('tokenResults');
const token = localStorage.getItem('access_token');
const refreshToken = localStorage.getItem('refresh_token');
const state = localStorage.getItem('oauth_state');
let html = '<h4>本地存储状态:</h4>';
html += `<p><strong>Access Token:</strong> ${token ? '已保存' : '未保存'}</p>`;
html += `<p><strong>Refresh Token:</strong> ${refreshToken ? '已保存' : '未保存'}</p>`;
html += `<p><strong>OAuth State:</strong> ${state ? '已保存' : '未保存'}</p>`;
if (token) {
html += '<h4>Token详情:</h4>';
html += `<p><strong>Token前50字符:</strong> ${token.substring(0, 50)}...</p>`;
html += `<button onclick="validateToken()">验证Token有效性</button>`;
}
results.innerHTML = html;
}
// 验证Token
async function validateToken() {
const token = localStorage.getItem('access_token');
const results = document.getElementById('tokenResults');
try {
const response = await fetch(oidcConfig.userInfoEndpoint, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const userInfo = await response.json();
results.innerHTML += `
<p class="success">✅ Token有效</p>
<pre>${JSON.stringify(userInfo, null, 2)}</pre>
`;
} else {
results.innerHTML += `<p class="error">❌ Token无效: ${response.status} ${response.statusText}</p>`;
}
} catch (error) {
results.innerHTML += `<p class="error">❌ Token验证失败: ${error.message}</p>`;
}
}
// 生成随机字符串
function generateRandomString() {
const array = new Uint32Array(28);
window.crypto.getRandomValues(array);
return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
}
</script>
</body>
</html>