-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcallback.html
More file actions
287 lines (244 loc) · 9.17 KB
/
callback.html
File metadata and controls
287 lines (244 loc) · 9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Processing | Authrim Example</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header>
<h1>Processing Authentication</h1>
</header>
<!-- Loading State -->
<div id="loading" class="card">
<div class="status status-loading">
<span class="spinner"></span> Processing authentication...
</div>
</div>
<!-- Success State -->
<div id="success" class="card hidden">
<div class="status status-success">
Authentication complete. Redirecting...
</div>
</div>
<!-- Error State -->
<div id="error" class="card hidden">
<div class="status status-error" id="error-message"></div>
<a href="login.html" class="btn btn-primary">Back to Login</a>
<a href="index.html" class="btn btn-secondary" style="margin-top: 0.5rem;">Back to Home</a>
</div>
<footer>
<p>Powered by <a href="https://authrim.com" target="_blank">Authrim</a></p>
</footer>
</div>
<!-- Load SDK -->
<script src="https://unpkg.com/@authrim/web@latest/dist/authrim-web.umd.global.js"></script>
<script src="config.js"></script>
<script>
// Elements
var $loading = document.getElementById('loading');
var $success = document.getElementById('success');
var $error = document.getElementById('error');
var $errorMessage = document.getElementById('error-message');
// Show state
function showState(state) {
$loading.classList.add('hidden');
$success.classList.add('hidden');
$error.classList.add('hidden');
switch (state) {
case 'loading':
$loading.classList.remove('hidden');
break;
case 'success':
$success.classList.remove('hidden');
break;
case 'error':
$error.classList.remove('hidden');
break;
}
}
// Show error
function showError(message) {
$errorMessage.textContent = message;
showState('error');
}
function handlePopupCallbacks() {
// OAuth popup callback (uses window.name)
if (
window.AuthrimWeb &&
typeof window.name === 'string' &&
window.name.indexOf('authrim:popup:') === 0 &&
typeof AuthrimWeb.handlePopupCallback === 'function'
) {
AuthrimWeb.handlePopupCallback();
return true;
}
// Direct Auth social popup callback
if (window.opener && window.opener.postMessage) {
var params = new URLSearchParams(window.location.search);
window.opener.postMessage(
{
type: 'authrim:social:callback',
code: params.get('code') || undefined,
error: params.get('error') || undefined,
error_description: params.get('error_description') || undefined,
},
window.location.origin
);
window.close();
return true;
}
return false;
}
/**
* Handoff Token処理(Smart Handoff SSO)
*
* SDK の auth.handoff.verifyAndSave() を使用した簡素化版
* 以下を自動実行:
* - ハンドオフトークン検証
* - State CSRF検証(handoff namespace)
* - localStorage への保存(SessionAuthImpl と同じ方法)
* - sessionStorage クリーンアップ
* - auth:login イベント発火
*/
async function handleHandoffCallback() {
var params = new URLSearchParams(window.location.search);
var handoffToken = params.get('handoff_token');
var state = params.get('state');
if (!handoffToken) {
return false; // ハンドオフフローではない
}
console.log('[Authrim] Handoff callback detected');
// URLからトークンを即座に消去(Referrer漏洩対策)
history.replaceState(null, '', window.location.pathname);
try {
var config = window.AUTHRIM_CONFIG;
// enableOAuth: OAuth機能を有効化(Silent Login SSO対応のため必要)
var auth = await AuthrimWeb.createAuthrim({
issuer: config.issuer,
clientId: config.clientId,
enableOAuth: true, // OAuth機能を有効化(Silent Login SSO対応)
});
// ✅ SDK統合メソッドを使用(約60行削減)
// ワンライナーでハンドオフ処理完了
// SDK内部で以下を自動実行:
// 1. ハンドオフトークン検証
// 2. State CSRF検証(handoff namespace)
// 3. localStorage への保存(SessionAuthImpl と同じ方法)
// 4. sessionStorage クリーンアップ
// 5. auth:login イベント発火
var result = await auth.handoff.verifyAndSave(handoffToken, state);
// 高度な用途: Storage key を取得
// var storageKey = auth.session.getStorageKey();
// console.log('[Authrim] Storage key:', storageKey);
console.log('[Authrim] Handoff login successful');
// Success表示
showState('success');
// リダイレクト
setTimeout(function() {
window.location.href = 'index.html';
}, 1000);
return true;
} catch (error) {
console.error('[Authrim] Handoff error:', error);
// SDKの統一エラー型を活用
if (error.code === 'HANDOFF_STATE_MISMATCH') {
showError('CSRF attack detected. Please try again.');
} else {
showError('An error occurred during handoff authentication');
}
return true;
}
}
// Main
async function main() {
try {
if (handlePopupCallbacks()) {
return;
}
// ハンドオフコールバック処理を優先(Smart Handoff SSO)
var handoffHandled = await handleHandoffCallback();
if (handoffHandled) {
return; // ハンドオフ処理完了
}
// Check configuration
if (!window.AUTHRIM_CONFIG?.issuer || window.AUTHRIM_CONFIG.issuer === 'https://your-tenant.authrim.com') {
showError('Please configure issuer and clientId in config.js');
return;
}
// Initialize SDK with OAuth enabled
var auth = await AuthrimWeb.createAuthrim({
issuer: window.AUTHRIM_CONFIG.issuer,
clientId: window.AUTHRIM_CONFIG.clientId,
enableOAuth: true,
});
// Initialize diagnostic logger if enabled
var diagConfig = window.AUTHRIM_CONFIG?.diagnostic;
if (diagConfig?.enabled && AuthrimWeb.createDiagnosticLogger) {
var diagnosticLogger = AuthrimWeb.createDiagnosticLogger({
enabled: true,
collectLogs: diagConfig.collectLogs !== false,
persistToStorage: diagConfig.persistToStorage !== false,
maxLogs: diagConfig.maxLogs ?? 1000,
sendToServer: diagConfig.sendToServer ?? false,
serverUrl: diagConfig.serverUrl ?? window.AUTHRIM_CONFIG.issuer,
clientId: window.AUTHRIM_CONFIG.clientId,
});
if (diagnosticLogger) {
auth.setDiagnosticLogger?.(diagnosticLogger);
window.AUTHRIM_DIAGNOSTIC_LOGGER = diagnosticLogger;
}
}
// First, try to handle as Silent Login callback
// This checks if the state parameter indicates a silent login flow
var silentResult = await auth.oauth.handleSilentCallback();
if (silentResult.status !== 'error' || silentResult.error !== 'not_silent_login') {
// This was a silent login callback - it handles its own redirects
// If we reach here, something unexpected happened
if (silentResult.status === 'error') {
showError('SSO Error: ' + silentResult.error + (silentResult.errorDescription ? ' - ' + silentResult.errorDescription : ''));
}
return;
}
var oauthFlow = sessionStorage.getItem('oauth_flow') === '1';
if (oauthFlow) {
sessionStorage.removeItem('oauth_flow');
var oauthResult = await auth.oauth.handleCallback(window.location.href);
if (oauthResult.error) {
showError(oauthResult.error.message);
return;
}
showState('success');
setTimeout(function() {
window.location.href = 'index.html';
}, 1000);
return;
}
// Not a silent login callback - handle as regular social login callback
if (!auth.social.hasCallbackParams()) {
// No callback parameters, redirect to home
window.location.href = 'index.html';
return;
}
// Handle regular social login callback
var result = await auth.social.handleCallback();
if (result.error) {
showError(result.error.message);
return;
}
// Success
showState('success');
setTimeout(function() {
window.location.href = 'index.html';
}, 1000);
} catch (e) {
console.error('Callback error:', e);
showError('Authentication processing failed: ' + e.message);
}
}
main();
</script>
</body>
</html>