Nuxt3 實作 Google 登入

用原生的方式實作看看吧


前言 — 版本資訊與設定

  • nuxt3版本是3.0.0-rc.4
  • 這是google 登入新版API的做法(因為舊版已經不能用了,即便官網的介紹還是以舊版為主)
  • 記得在oath2那個介面中,同時設定http://localhost:3000http://localhost,讓開發環境也能被授權使用google login。
  • 如果是使用react或是原生html, js,則在head自行添加script <script src=”https://accounts.google.com/gsi/client” async defer />

核心 — 主要函式

  • initialize:進行google api初始化
  • renderButton:負責渲染按鈕

實作 — vue和nuxt3分別實作

  • 重點函式:initialize和renderButton

    if (!google) return; // console.log(google); // 初始化認證登入 google.accounts.id.initialize({ client_id: props.googleLoginButtonProps.clientId, callback: props.googleLoginButtonProps.onCredentialResponse, }); // 渲染按鈕 google.accounts.id.renderButton( document.getElementById('g_id_onload'), { type: 'profile', } );
  • 登入按鈕的 vue組件實作(GoogleLoginButton)

    <template> <div id="g_id_onload"></div> </template> <script lang="ts"> import { defineComponent, PropType } from 'vue'; declare const google: { accounts: { id: { initialize: (options: { client_id: string; callback: (res?: CredentialRes) => any; }) => any; renderButton: ( el: HTMLElement, conf: Partial<GsiButtonConfigurationOptions> ) => any; }; }; }; interface CredentialRes { clientId: string; credential: string; select_by: string; } // https://developers.google.com/identity/gsi/web/reference/js-reference#GsiButtonConfiguration interface GsiButtonConfigurationOptions { type: string; theme: string; size: string; text: string; shape: string; logo_alignment: string; width: string; locale: string; } export interface GoogleLoginButtonProps { clientId: string; renderButtonOptions?: Partial<GsiButtonConfigurationOptions>; onCredentialResponse?: (res: CredentialRes) => any; } export default defineComponent({ name: 'GoogleLoginButton', props: { googleLoginButtonProps: { type: Object as PropType<GoogleLoginButtonProps>, default: () => ({}), }, }, setup(props) { onMounted(() => { if (!google) return; // console.log(google); google.accounts.id.initialize({ client_id: props.googleLoginButtonProps.clientId, callback: props.googleLoginButtonProps.onCredentialResponse, }); google.accounts.id.renderButton( document.getElementById('g_id_onload'), { type: 'profile', ...props.googleLoginButtonProps.renderButtonOptions, } ); }); return {}; }, }); </script> <style lang="scss" scoped></style> ```
  • nuxt實作整合應用

    • nuxt.cofig.ts
      • 引入script
      • 添加env
    import { defineNuxtConfig } from 'nuxt'; export default defineNuxtConfig({ app: { head: { script: [ { src: 'https://accounts.google.com/gsi/client', async: true, defer: true, }, ], }, }, publicRuntimeConfig: { NUXT_ENV_GOOGLE_CLIENT_ID: process.env.NUXT_ENV_GOOGLE_CLIENT_ID, }, })
    • .env
    NUXT_ENV_GOOGLE_CLIENT_ID=你的google client id
    • 引用GoogleLoginButton的組件
    <template> <div> <GoogleLoginButton :googleLoginButtonProps="googleLoginButtonProps" /> </div> </template> <script lang="ts"> // import 組件... setup() { const config = useRuntimeConfig(); const handleCredentialResponse = (res: any) => { console.log(res); }; const googleLoginButtonProps = computed( (): GoogleLoginButtonProps => ({ clientId: config.NUXT_ENV_GOOGLE_CLIENT_ID, onCredentialResponse: handleCredentialResponse, }) ); return ({ googleLoginButtonProps }) } </script>

REF