Vue3 串接 Google OAuth 登入 【2022 最新】

前言

大家好,我是 Ryan,这篇文章是我参与 iThome 2022 铁人赛时与大家分享使用 Nuxt 3 串接 Google OAuth 登入的额外分享,因为在使用 Nuxt 3 串接 Google OAuth 其实等同于在 Vue 3 中做实现,所以独立了一篇 Vue 3 的範例来分享给大家。

为了让专案更乾净,本篇範例使用的是 Vue 3 + Vite 的模板,大家也可以参考下列指令做建立。

npm create vite@latest vue3-google-oauth-example -- --template vue

使用 OAuth 2.0 存取 Google API

首先,我们需要有一组 Google OAuth 使用的 Client ID,你可以到 Google Console 新增一个「OAuth 2.0 用户端 ID」,这里我就不再赘述网页应用程式用的申请过程。

这边提醒,在建立 OAuth Client ID 时,已授权的 JavaScript 来源,记得填写上您的正式环境或开发环境的 Domain,且建议使用 HTTPS。
http://img2.58codes.com/2024/20152617spwcOfXg04.png

完成后,记得保管好用户端密码,用户端 ID (Client ID) 是我们稍后会需要的,用户端编号格式大概如:

168152363730-b37gnijdpa2rdvvbq0qc29cjh4082t3b.apps.googleusercontent.com

接下来,安装 Vue 的 Google OAuth 插件,这边使用的是 vue3-google-login,也有不错的说明文件可以参考。

使用 NPM 安装 vue3-google-login。

npm install -D vue3-google-login

接着我们在元件中可以直接使用 <GoogleLogin> 元件,并添加一个 callback 属性。

<script setup>import { ref } from 'vue'const data = ref()const callback = (response) => {  data.value = response}</script><template>  <div>    <GoogleLogin :callback="callback" />    <p>      {{ data }}    </p>  </div></template><style scoped>p {  margin-top: 12px;  word-break: break-all;}</style>

接着我们使用 npm run dev 来启动开发伺服器,就能发现使用 Google 帐号登入成功后,所返回的 Credential。
http://img2.58codes.com/2024/8NSdQGl.gif

One Tap prompt

你可以在 <GoogleLogin> 元件添加 prompt 属性并设为 true,这样就能同时启用 Google 一键登入 (One Tap prompt) 的功能啰!

<GoogleLogin :callback="callback" prompt/>

或者也可以在 onMounted 中呼叫 vue3-google-login 的 googleOneTap() 方法,来单独使用 One Tap prompt。

<script setup>import { onMounted } from 'vue'import { googleOneTap } from 'vue3-google-login'onMounted(() => {  googleOneTap()    .then((response) => {      console.log(response)    })    .catch((error) => {      console.error(error)    })})</script>

http://img2.58codes.com/2024/Z6tDWPv.gif

自订按钮

如果你想自订登入按钮的样式,可以在 <GoogleLogin> 的预设插槽 (Slot) 做建立。

<template>  <GoogleLogin :callback="callback">    <button>使用 Google 进行登入</button>  </GoogleLogin></template>

使用自订按钮会让 OAuth 流程稍微有点不一样,当你登入成功后预设会回传 Auth Code。

如果设定属性 popup-type="TOKEN",则回传 Access Token。

<template>  <GoogleLogin :callback="callback" popup-type="TOKEN">    <button>使用 Google 进行登入</button>  </GoogleLogin></template>

使用 googleTokenLogin()

在元件中我们也可以自己建立 handleGoogleAccessTokenLogin 点击事件,呼叫 googleTokenLogin() 方法并传入设定在 Runtime Config 中的 Google Client ID,这样点击登入按钮就能处理 Google 登入取得 Access Token。

<script setup>import { ref } from 'vue'import { googleTokenLogin } from 'vue3-google-login'const GOOGLE_CLIENT_ID = '这边放上你的 Google Client ID'const data = ref()const handleGoogleAccessTokenLogin = () => {  googleTokenLogin({    clientId: GOOGLE_CLIENT_ID  }).then((response) => {    data.value = response  })}</script>

建立一个登入按钮来呼叫 handleGoogleAccessTokenLogin 点击事件。

<template>  <div>    <button      type="button"      @click="handleGoogleAccessTokenLogin"    >      使用 Google 进行登入    </button></template>

使用 vue3-google-login 提供的 googleTokenLogin() 方法,我们就能取得 Google 使用者的 Access Token 啰!
http://img2.58codes.com/2024/01TiBUZ.gif

使用 googleAuthCodeLogin()

我们也可以使用 googleAuthCodeLogin() 来取得 Auth Code。

<script setup>import { ref } from 'vue'import { googleAuthCodeLogin } from 'vue3-google-login'const GOOGLE_CLIENT_ID = '这边放上你的 Google Client ID'const data = ref()const handleGoogleAuthCodeLogin = () => {  googleAuthCodeLogin({    clientId: GOOGLE_CLIENT_ID  }).then((response) => {    data.value = response  })}</script>

建立一个登入按钮来呼叫 handleGoogleAuthCodeLogin 点击事件。

<template>  <div>    <button      type="button"      @click="handleGoogleAuthCodeLogin"    >      使用 Google 进行登入    </button></template>

取得的就会是 Auth Code。
http://img2.58codes.com/2024/E4JokY0.gif

伺服器端验证

当使用者于前端成功登入后,通常会传至后端进行登入或记录使用者,再产生使用于网站的 Token、Cookie 或 Session 等,以供后续的网站验证做使用。

我们可使用 google-auth-library 于后端进行一系列的验证或取得使用者资讯。

使用 NPM 安装 google-auth-library。

npm install -D google-auth-library

接下来,我们就能依照不同的登入方式取得的 CredentialAccess TokenAuth Code 送至后端做验证。

验证 Access Token

import { OAuth2Client } from 'google-auth-library'export default (async (accessToken) => {  const oauth2Client = new OAuth2Client()  oauth2Client.setCredentials({ access_token: accessToken })  const userInfo = await oauth2Client    .request({      url: 'https://www.googleapis.com/oauth2/v3/userinfo'    })    .then((response) => response.data)    .catch(() => null)  oauth2Client.revokeCredentials()  return {    id: userInfo.sub,    name: userInfo.name,    avatar: userInfo.picture,    email: userInfo.email,    emailVerified: userInfo.email_verified,  }})

验证 Credential

在元件中,我们使用的登入方式如果是Google 预设渲染的按钮或 One Tap prompt,回传值就会包含 Credential,我们将就可使用下面修改后的 Server API 进行验证。

import { OAuth2Client } from 'google-auth-library'export default (async (credential) => {  const oauth2Client = new OAuth2Client()  const ticket = await oauth2Client.verifyIdToken({    idToken: credential,  })  const payload = ticket.getPayload()  return {    id: payload.sub,    name: payload.name,    avatar: payload.picture,    email: payload.email,    emailVerified: payload.email_verified  }})

验证 Auth Code

import { OAuth2Client } from 'google-auth-library'export default (async (authCode) => {  const oauth2Client = new OAuth2Client({    clientId: '你的 Google Client ID',    clientSecret: '你的 Google Client Secret',    redirectUri: '你的 Google Redirect Uri'  })  let { tokens } = await oauth2Client.getToken(authCode)  client.setCredentials({ access_token: tokens.access_token })  const userInfo = await oauth2Client    .request({      url: 'https://www.googleapis.com/oauth2/v3/userinfo'    })    .then((response) => response.data)    .catch(() => null)  oauth2Client.revokeCredentials()  return {    id: userInfo.sub,    name: userInfo.name,    avatar: userInfo.picture,    email: userInfo.email,    emailVerified: userInfo.email_verified,  }})

小结

这篇文章记录了实现了串接 Google OAuth 登入,大家可以在依照使用情境自己挑选登入方式并将 Access Token 等其他资讯发送至后端进行验证,后续也能将使用者资讯储存到资料库中,有了资料库我们就能依照使用者资讯,来比对资料库进行注册、验证登入及产生后续的 Session 或 Cookie 等。


感谢大家的阅读,欢迎大家给予建议 :)

此外我正在参与 iThome 铁人赛,主题是 Nuxt 3 学习笔记,
如果对 Nuxt 3 系列感兴趣,可以订阅接收通知,也欢迎分享给喜欢或正在学习 Nuxt 3 的伙伴。

範例程式码

Vue 3 - 使用 Google OAuth 登入範例

参考文件

Vue 3 Google Login使用 OAuth 2.0 存取 Google API

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章