auth_callback.html 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta content="width=device-width, initial-scale=1.0" name="viewport">
  6. <title>SSO 登录回调</title>
  7. <script src="{{ url_for('static', filename='js/tailwindcss.js') }}"></script>
  8. <link href="{{ url_for('static', filename='fontawesome/css/all.min.css') }}" rel="stylesheet">
  9. <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
  10. </head>
  11. <body class="min-h-screen flex items-center justify-center" style="background-color: #0a192f;">
  12. <div class="tech-panel p-10 rounded-xl w-full max-w-md shadow-2xl border-blue-500/50 text-center">
  13. <div id="loading-view">
  14. <i class="fas fa-spinner fa-spin text-5xl text-cyan-400 mb-6"></i>
  15. <h2 class="text-2xl font-bold text-cyan-300 mb-2">SSO 登录中</h2>
  16. <p class="text-gray-400">正在验证身份,请稍候...</p>
  17. </div>
  18. <div id="error-view" class="hidden">
  19. <i class="fas fa-exclamation-circle text-5xl text-red-400 mb-6"></i>
  20. <h2 class="text-2xl font-bold text-red-300 mb-2">登录失败</h2>
  21. <p id="error-message" class="text-gray-400 mb-6"></p>
  22. <a href="{{ url_for('main.login') }}" class="tech-button inline-block px-6 py-3 bg-cyan-600 hover:bg-cyan-500 text-white font-bold rounded-lg transition duration-300">
  23. <i class="fas fa-arrow-left mr-2"></i> 返回登录页
  24. </a>
  25. </div>
  26. <div id="success-view" class="hidden">
  27. <i class="fas fa-check-circle text-5xl text-green-400 mb-6"></i>
  28. <h2 class="text-2xl font-bold text-green-300 mb-2">登录成功</h2>
  29. <p class="text-gray-400">正在跳转首页...</p>
  30. </div>
  31. </div>
  32. <script>
  33. (async function () {
  34. const code = '{{ code }}';
  35. const loadingView = document.getElementById('loading-view');
  36. const errorView = document.getElementById('error-view');
  37. const successView = document.getElementById('success-view');
  38. const errorMessage = document.getElementById('error-message');
  39. if (!code) {
  40. showError('缺少授权码');
  41. return;
  42. }
  43. try {
  44. const response = await fetch('/api/oauth/exchange-code', {
  45. method: 'POST',
  46. headers: { 'Content-Type': 'application/json' },
  47. body: JSON.stringify({ code: code })
  48. });
  49. const result = await response.json();
  50. if (result.code === '000000') {
  51. // 保存 Token
  52. localStorage.setItem('token', result.data.token);
  53. localStorage.setItem('refresh_token', result.data.refresh_token);
  54. localStorage.setItem('user', JSON.stringify(result.data.user));
  55. // 显示成功,跳转首页
  56. loadingView.classList.add('hidden');
  57. successView.classList.remove('hidden');
  58. setTimeout(function () {
  59. window.location.href = '{{ url_for("main.dashboard") }}';
  60. }, 800);
  61. } else {
  62. showError(result.message || '登录失败');
  63. }
  64. } catch (err) {
  65. showError('网络请求失败: ' + err.message);
  66. }
  67. function showError(msg) {
  68. loadingView.classList.add('hidden');
  69. errorMessage.textContent = msg;
  70. errorView.classList.remove('hidden');
  71. }
  72. })();
  73. </script>
  74. </body>
  75. </html>