index.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <script setup>
  2. const emit = defineEmits(['success', 'error'])
  3. const loading = ref(false)
  4. const clientID = '482169597782-nic3d8bo67o0gmq93cmgao7050ets16n.apps.googleusercontent.com'
  5. onMounted(() => {
  6. const script = document.createElement('script')
  7. script.src = 'https://accounts.google.com/gsi/client'
  8. script.async = true
  9. script.defer = true
  10. document.head.appendChild(script)
  11. })
  12. /**
  13. * 初始化 Google Auth
  14. */
  15. function initializeGoogleAuth(resolve, reject) {
  16. return window.google.accounts.oauth2.initTokenClient({
  17. client_id: clientID,
  18. scope: 'email profile',
  19. callback: async (response) => {
  20. try {
  21. // 获取用户基本信息
  22. const userInfo = await fetchUserInfo(response.access_token)
  23. const res = {
  24. token: response.access_token,
  25. userInfo,
  26. }
  27. resolve(res)
  28. }
  29. catch (error) {
  30. reject(error)
  31. }
  32. },
  33. error_callback: (error) => {
  34. reject(error)
  35. },
  36. })
  37. }
  38. /**
  39. * 获取用户详细信息
  40. */
  41. async function fetchUserInfo(accessToken) {
  42. const res = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
  43. headers: {
  44. Authorization: `Bearer ${accessToken}`,
  45. },
  46. })
  47. if (!res.ok)
  48. throw new Error('获取用户信息失败')
  49. return await res.json()
  50. }
  51. // 触发登录
  52. function handleGoogleLogin() {
  53. return new Promise((resolve, reject) => {
  54. if (!window.google) {
  55. const t = setTimeout(() => {
  56. clearTimeout(t)
  57. ElMessage.error('当前环境不支持 Google 登录,请使用其他方式登录')
  58. reject(new Error('Google SDK not loaded'))
  59. }, 1000)
  60. return
  61. }
  62. const client = initializeGoogleAuth(resolve, reject)
  63. client.requestAccessToken()
  64. })
  65. }
  66. async function onGoogleLogin() {
  67. try {
  68. loading.value = true
  69. const result = await handleGoogleLogin()
  70. loading.value = false
  71. console.log('result------登陆成功', result)
  72. emit('success', result)
  73. }
  74. catch (error) {
  75. loading.value = false
  76. emit('error', error)
  77. }
  78. }
  79. </script>
  80. <template>
  81. <button id="google-login-button" class="b-rd-200px w-100% bg-#fff text-#333 b-1px b-solid b-#D8D8D8 h-48px lh-48px hover:b-#9B6CFF disabled:hover:b-#D8D8D8 cursor-pointer mb-24px text-14px fw-500" :disabled="loading" @click="onGoogleLogin">
  82. <span v-if="loading">登录中...</span>
  83. <div v-else class="flex justify-center items-center">
  84. <img src="@/assets/images/google_logo.png" alt="" class="w-24px h-24px mr-10px">
  85. Continue with Google
  86. </div>
  87. </button>
  88. </template>
  89. <style scoped>
  90. </style>