index.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <div v-loading="loading" class="social-callback"></div>
  3. </template>
  4. <script setup lang="ts">
  5. import { login, callback } from '@/api/login';
  6. import { setToken, getToken } from '@/utils/auth';
  7. import { LoginData } from '@/api/types';
  8. const route = useRoute();
  9. const loading = ref(true);
  10. /**
  11. * 接收Route传递的参数
  12. * @param {Object} route.query.
  13. */
  14. const code = route.query.code as string;
  15. const state = route.query.state as string;
  16. const source = route.query.source as string;
  17. const stateJson = JSON.parse(atob(state));
  18. const tenantId = (stateJson.tenantId as string) ? (stateJson.tenantId as string) : '000000';
  19. const domain = stateJson.domain as string;
  20. const processResponse = async (res: any) => {
  21. if (res.code !== 200) {
  22. throw new Error(res.msg);
  23. }
  24. if (res.data !== null) {
  25. setToken(res.data.access_token);
  26. }
  27. ElMessage.success(res.msg);
  28. setTimeout(() => {
  29. location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
  30. }, 2000);
  31. };
  32. const handleError = (error: any) => {
  33. ElMessage.error(error.message);
  34. setTimeout(() => {
  35. location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
  36. }, 2000);
  37. };
  38. const callbackByCode = async (data: LoginData) => {
  39. try {
  40. const res = await callback(data);
  41. await processResponse(res);
  42. loading.value = false;
  43. } catch (error) {
  44. handleError(error);
  45. }
  46. };
  47. const loginByCode = async (data: LoginData) => {
  48. try {
  49. const res = await login(data);
  50. await processResponse(res);
  51. loading.value = false;
  52. } catch (error) {
  53. handleError(error);
  54. }
  55. };
  56. const init = async () => {
  57. // 如果域名不相等 则重定向处理
  58. const host = window.location.host;
  59. if (domain !== host) {
  60. // 只允许跳转到本校域名,防止授权码被带到第三方站点
  61. const domainHost = String(domain || '').split(':')[0].toLowerCase();
  62. const trusted = domainHost === 'hzdyjsxy.cn' || domainHost.endsWith('.hzdyjsxy.cn') || domainHost === 'localhost' || domainHost === '127.0.0.1';
  63. if (!trusted) {
  64. handleError(new Error('非法的回调域名'));
  65. return;
  66. }
  67. const urlFull = new URL(window.location.href);
  68. urlFull.host = domain;
  69. window.location.href = urlFull.toString();
  70. return;
  71. }
  72. const data: LoginData = {
  73. socialCode: code,
  74. socialState: state,
  75. tenantId: tenantId,
  76. source: source,
  77. clientId: import.meta.env.VITE_APP_CLIENT_ID,
  78. grantType: 'social'
  79. };
  80. if (!getToken()) {
  81. await loginByCode(data);
  82. } else {
  83. await callbackByCode(data);
  84. }
  85. };
  86. onMounted(() => {
  87. nextTick(() => {
  88. init();
  89. });
  90. });
  91. </script>