feat: 谷歌登录注册
This commit is contained in:
189
src/views/login/components/GoogleLogin.vue
Normal file
189
src/views/login/components/GoogleLogin.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<div class="Container">
|
||||
<div class="g_id_signin" id="g_id_signin"></div>
|
||||
<div class="icon">
|
||||
<img :src="google" class="google-icon" />
|
||||
<span>{{ text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { showToast } from 'vant'
|
||||
import { google } from '@/assets/base64'
|
||||
|
||||
// 定义 props
|
||||
defineProps({
|
||||
text: {
|
||||
type: String,
|
||||
default: 'Sign in with Google'
|
||||
}
|
||||
})
|
||||
|
||||
// 定义 emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'googelLogin', code: string): void
|
||||
}>()
|
||||
|
||||
// JWT 解码函数
|
||||
function decodeJWT(token: string) {
|
||||
const base64Url = token.split('.')[1]
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
|
||||
const jsonPayload = decodeURIComponent(
|
||||
atob(base64)
|
||||
.split('')
|
||||
.map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
||||
})
|
||||
.join('')
|
||||
)
|
||||
return JSON.parse(jsonPayload)
|
||||
}
|
||||
|
||||
// 处理 Google 登录回调
|
||||
const handleCredentialResponse = async (response: { credential: string }) => {
|
||||
// 获取回调响应的凭证数据 然后拿这个凭证给后台,后台jwt进行解析获取登录信息
|
||||
console.log('Encoded JWT ID token: ' + response.credential)
|
||||
const responsePayload = decodeJWT(response.credential)
|
||||
console.log('Decoded JWT ID token fields:')
|
||||
console.log(' Full Name: ' + responsePayload.name)
|
||||
console.log(' Given Name: ' + responsePayload.given_name)
|
||||
console.log(' Family Name: ' + responsePayload.family_name)
|
||||
console.log(' Unique ID: ' + responsePayload.sub)
|
||||
console.log(' Profile image URL: ' + responsePayload.picture)
|
||||
console.log(' Email: ' + responsePayload.email)
|
||||
|
||||
const code = response.credential
|
||||
emit('googelLogin', code)
|
||||
window.isAddGmail = false
|
||||
}
|
||||
|
||||
// 配置数据
|
||||
const data = reactive({
|
||||
// scriptSrc:'https://apis.google.com/js/platform.js',
|
||||
scriptSrc: 'https://accounts.google.com/gsi/client',
|
||||
script: null
|
||||
})
|
||||
|
||||
console.log(import.meta.env.VITE_USER_NODE_ENV)
|
||||
|
||||
// 根据环境设置 Google Client ID
|
||||
const GOOGLE_CLIENT_ID = '216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com'
|
||||
|
||||
// 创建 Gmail 登录
|
||||
const createGmailLogin = async () => {
|
||||
const existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`)
|
||||
if (!window.isAddGmail) {
|
||||
if (!existingScript) {
|
||||
window.isAddGmail = true
|
||||
await new Promise<void>((resolve) => {
|
||||
const script = document.createElement('script')
|
||||
script.onload = () => {
|
||||
resolve()
|
||||
}
|
||||
document.body.appendChild(script)
|
||||
script.src = data.scriptSrc
|
||||
})
|
||||
}
|
||||
window.google.accounts.id.initialize({
|
||||
// 主要就是填写client_id
|
||||
client_id: GOOGLE_CLIENT_ID,
|
||||
auto_select: false,
|
||||
callback: handleCredentialResponse,
|
||||
// context:"signin",
|
||||
ux_mode: 'popup',
|
||||
itp_support: true
|
||||
})
|
||||
console.log(document.querySelector('.Container #g_id_signin'))
|
||||
window.google.accounts.id.renderButton(document.querySelector('.Container #g_id_signin'), {
|
||||
type: 'standard', //icon为只有一个icon
|
||||
shape: 'circle',
|
||||
theme: 'outline',
|
||||
size: 'large',
|
||||
logo_alignment: 'center'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const toGmailLogin = () => {
|
||||
showToast('Google login is not available yet')
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`)
|
||||
if (existingScript) {
|
||||
existingScript.remove()
|
||||
window.isAddGmail = false
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
createGmailLogin()
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.Container {
|
||||
width: 100%;
|
||||
height: 10.6rem;
|
||||
padding: 1.6rem;
|
||||
border: 0.2rem solid #fff;
|
||||
border-radius: 7rem;
|
||||
font-size: 3.83rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
column-gap: 3.1rem;
|
||||
margin-bottom: 1.67rem;
|
||||
|
||||
:deep(.nsm7Bb-HzV7m-LgbsSe-bN97Pc-sM5MNb) {
|
||||
justify-content: center;
|
||||
.nsm7Bb-HzV7m-LgbsSe-Bz112c {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
:deep(.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK) {
|
||||
width: 100%;
|
||||
height: 10.6rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4rem;
|
||||
padding: 1.3rem 4.6rem;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
background: transparent;
|
||||
pointer-events: none;
|
||||
column-gap: 3.1rem;
|
||||
}
|
||||
|
||||
.g_id_signin {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
:deep(.S9gUrf-YoZ4jf) {
|
||||
&,
|
||||
& > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
iframe {
|
||||
zoom: 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.google-icon {
|
||||
width: 4.8rem;
|
||||
height: 4.8rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user