# 實作Google登入 ## 1. 到 [Google Cloud API和服務](https://console.cloud.google.com/apis/dashboard) 建立OAuth憑證 ![](https://hackmd.io/_uploads/HkuRY301p.png) ## 2. 記得加入使用憑證的網址 ![](https://hackmd.io/_uploads/SkcR520Ja.png) ## 3. 安裝 `vue-google-login` 套件 * [套件詳細說明文件](https://devbaji.github.io/vue3-google-login/) 在終端機輸入: ``` npm install -D vue3-google-login ``` ## 4. 在 `nuxt.config.ts` 內的 `runtimeConfig` 新增參數 ```typescript runtimeConfig: { public: { googleClientId: "你的google client id", }, }, ``` ![](https://hackmd.io/_uploads/HybmThCkp.png) ## 5. 建立`plugins/vue3-goolge-login.client.js` ![](https://hackmd.io/_uploads/Bkaoo3R1a.png) `vue3-goolge-login.client.js` 內容如下: ```javascript import vue3GoogleLogin from "vue3-google-login"; export default defineNuxtPlugin((nuxtApp) => { const runtimeConfig = useRuntimeConfig(); const { googleClientId: GOOGLE_CLIENT_ID } = runtimeConfig.public; nuxtApp.vueApp.use(vue3GoogleLogin, { clientId: GOOGLE_CLIENT_ID, }); }); ``` ## 6. 使用套件 方式有很多種,可以 call function 或 使用 component。 ### 使用component ```javascript <template> <GoogleLogin :callback="callback"/> </template> <script setup> const callback = (response) => { // This callback will be triggered when the user selects or login to // his Google account from the popup console.log("Handle the response", response) } </script> ``` ### 使用 function #### `googleAuthCodeLogin` ```javascript <script setup> import { googleAuthCodeLogin } from "vue3-google-login" const login = () => { googleAuthCodeLogin().then((response) => { console.log("Handle the response", response) }) } </script> <template> <button @click="login">Login Using Google</button> </template> ``` #### `googleTokenLogin` ``` <script setup> import { googleTokenLogin } from "vue3-google-login" const login = () => { googleTokenLogin().then((response) => { console.log("Handle the response", response) }) } </script> <template> <button @click="login">Login Using Google</button> </template> ``` ## 7. 驗證 或 獲取 user information ### 安裝 `accessToken.access_token` ``` npm install -D google-auth-library ``` ### 驗證 `Access Token` 新增一個 Server API,只接受 **POST** 方法,在 Body 中夾帶 `accessToken` 發送至後端。 建立 `./server/api/auth/google.post.js`,內容如下: ```javascript import { OAuth2Client } from 'google-auth-library' export default defineEventHandler(async (event) => { const body = await readBody(event) const oauth2Client = new OAuth2Client() oauth2Client.setCredentials({ access_token: body.accessToken }) const userInfo = await oauth2Client .request({ url: 'https://www.googleapis.com/oauth2/v3/userinfo' }) .then((response) => response.data) .catch(() => null) oauth2Client.revokeCredentials() if (!userInfo) { throw createError({ statusCode: 400, statusMessage: 'Invalid token' }) } return { id: userInfo.sub, name: userInfo.name, avatar: userInfo.picture, email: userInfo.email, emailVerified: userInfo.email_verified, } }) ``` 調整元件內的登入流程。 ```javascript <script setup> import { googleTokenLogin } from 'vue3-google-login' const runtimeConfig = useRuntimeConfig() const { googleClientId: GOOGLE_CLIENT_ID } = runtimeConfig.public const userInfo = ref() const handleGoogleLogin = async () => { const accessToken = await googleTokenLogin({ clientId: GOOGLE_CLIENT_ID }).then((response) => response?.access_token) if (!accessToken) { return '登入失敗' } const { data } = await useFetch('/api/auth/google', { method: 'POST', body: { accessToken }, initialCache: false }) userInfo.value = data.value } </script> ``` ## 參考資料 https://ithelp.ithome.com.tw/articles/10304148 https://dotblogs.com.tw/shadow/2018/07/05/152206