前言
最近做毕业设计,前端用vue2,想实现一个谷歌登录的功能,先后尝试过第三方的包以及自己封装,最终发现还是Firebase最香。
我是普通本科菜鸟,接触前端时间不长,经验很不丰富,这篇博客用来记录一下折磨了我一天的故事。
先分享一下踩过的坑:
先说第三方包的问题,vue2的谷歌登录插件主要是vue-google-oauth2和vue-google-signin-button-directive,网上教程很多都推荐这两个。
vue-google-oauth2使用老版api,老版api在2023年3月31日停用(https://developers.google.com/identity/sign-in/web/sign-in),插件也已经停止维护,自然是不再考虑使用了。
vue-google-signin-button-directive按照网上的说法,是最方便快捷的方案,实测下来也确实是这样,前提是他能正常工作。然而,他会报{error: "popup_closed_by_user"}的错误,作者也没有回应解决方法。
PS:到这里需要羡慕一下vue3,vue3的插件vue3-google-login能正常工作。
现有插件不好使,我尝试自己封装,然而谷歌文档实在是毫无帮助,也没给任何例子,我跟着Google OAuth Authentication Vue.js and Node.js这篇帖子DIY。原贴主要用TypeScript,我不会ts,用async和await改造成JavaScript。
需要先说一下前端谷歌登录的流程,我们先向谷歌控制台申请一个OAuth2 Client ID,用这个ID去请求https://accounts.google.com/o/oauth2/v2/auth api。一切顺利的话谷歌会给我们返回一个链接,链接参数中包括一个“code”(类似于一个token),这个链接就是选择用哪一个谷歌账户登录的页面,直接window.open打开就可以选择要登录的账户。当我们点击账户的时候,需要带着那个“code”以及你的OAuth2 Client ID、ID的secret去请求https://oauth2.googleapis.com/token api,获得两个token。最后,拿着这两个token去向https://www.googleapis.com/oauth2/v2/userinfo请求所点击的谷歌账户的信息。
那么,我卡在了哪一步呢?
我能成功拿到第一次请求的code,但是第二次请求token一直报400,估计是参数没给对,谷歌文档实在是毫无帮助。
DIY,卒。
最后,我发现了Firebase这个神奇的东西。一直以为Firebase只是云服务商,提供服务托管和存储,没想到还提供完善的用户登录解决方案,里面就有现成的谷歌登录接口。
用Firebase做谷歌登录
网上教程很多,Firebase操作也方便,说说大致流程。
在Firebase新建项目,然后选择“构建” -> “Authentication”,在“登录提供方”中选择Google,直接点击保存。Firebase会在你的谷歌云中自动创建API 密钥和OAuth 2.0 客户端 ID。创建完成后,Firebase会告诉你如何在项目中安装Firebase的包,以及如何配置FirebaseConfig。也可以在“项目设置” -> “您的应用”中查看SDK 设置和配置。
第二步就是前端做谷歌登录:
<template>
<el-button size="small" @click="google" round><font-awesome-icon style="color: red;" icon="fa-brands fa-google" /></el-button>
</template>
样式用了ElementUI和Fontawesome,不重要。
import { initializeApp } from "firebase/app";
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
import { Loading } from 'element-ui';
import {firebaseConfig} from "@/utils/firebase";
export default{
methods:{
async google() {
initializeApp(firebaseConfig);
const provider = new GoogleAuthProvider();
const auth = getAuth();
try {
let loadingInstance = Loading.service({ fullscreen: true });
let googleResult = await signInWithPopup(auth, provider);
const user = googleResult.user;
let loginResult = await this.$api.google(user.email, user.displayName); // 这里是自己的后端接口,用于谷歌登录/注册
if(loginResult.data.code === 200) { // 正常情况
// 前端设置用户信息和token略
this.$message({
type: 'success',
message: "欢迎" + user.displayName
});
loadingInstance.close();
await this.$router.go(-1);
} else if(loginResult.data.code === 215) { // 这个谷歌邮箱已经通过邮箱注册
loadingInstance.close();
this.$alert("该谷歌邮箱已经通过邮箱注册,请通过密码登录", {
confirmButtonText: "确认",
callback: () => {}
}).then(() => {});
}
} catch (e) {
this.$alert("未知错误", {
confirmButtonText: "确认",
callback: () => {}
}).then(() => {});
}
}
}
}
后端逻辑:
判断邮箱是否注册?
是 ->
判断邮箱是通过谷歌注册还是邮箱注册?
case 谷歌 -> 登录成功,返回数据库保存的用户信息
case 邮箱 -> 登录失败,告诉前端换一种登录方式
否 ->
注册新用户,标记为通过谷歌注册,返回登录成功
当你把FirebaseConfig的代码推到GitHub十分钟后,会收到谷歌的邮件,告诉你你的API Key泄露了。这个API Key是必须在前端暴露的(推不推GitHub也无所谓了),所以我们需要把API Key的权限修改一下,避免被人滥用。
打开谷歌云控制台,选择你的这个项目,“API和服务” -> 凭据 -> API密钥。
修改API密钥,设置应用限制为“网站”,在“网站限制”中添加localhost以及你的域名。
API 限制设为“限制密钥”,选定“Identity Toolkit API”、“Token Service API”两个API。
保存,大功告成。
谷歌登录面板相关问题
谷歌登录面板通过“API和服务”下的“OAuth 同意屏幕”修改,可以设定你网站的隐私权政策链接以及服务条款链接,还有你要获取用户的哪些数据。
用Firebase做谷歌登录会有一个问题,Firebase代理了从你的网站到谷歌中间的通信,Firebase建项目时会自动给你分配一个域名,格式为[项目 ID].firebaseapp.com,谷歌登录面板上显示的是Firebase这个域名,如图。
对于这个问题,Firebase官网给了解决方法:https://firebase.google.com/docs/auth/web/google-signin#customizing-the-redirect-domain-for-google-sign-in
去Firebase,“构建” -> “Hosting”,点击“开始使用”,不用管他让做的步骤,直接去第三步,点“继续前往控制台”。进到Hosting的信息中心,“添加自定义网域”,输入auth.你的域名,比如auth.xiaoming.site,Firebase会告诉你解析的IP地址。添加完成后,鼠标覆盖到域名那行,点击右侧三个点 -> “修改网域”,选择“将此网域重定向至其他网域”,填入你的域名,比如xiaoming.site。
去域名商或者DNS服务商控制台,给域名多配一个DNS解析,类型选A,名字填auth,内容填Firebase给你的IP。
去谷歌云控制台,API和服务 -> 凭据 -> OAuth 2.0 客户端 ID,点击修改,在“已获授权的重定向 URI”一栏(找了半天才发现居然是在客户端ID里),填入https://auth.xiaoming.site/__/auth/handler(一定要加上后面的“/__/auth/handler”),保存。然后前往“OAuth 同意屏幕”,点击修改应用,划到“已授权的应用网域”,可以看到除了firebaseapp.com之外,多了一个xiaoming.site,说明已经修改成功。
去你的前端代码,FirebaseConfig部分,添加一个参数 authDomain: 'auth.xiaoming.site'。
大功告成!
完成后你的谷歌登录面板显示的域名就是xiaoming.site,点击“继续前往xiaoming.site”链接,弹框里显示开发者信息、你的Firebase账户电子邮件地址,以及“选择帐号后,您将会转到:https://auth.xiaoming.site”。访问auth.xiaoming.site,会重定向至主域名xiaoming.site。
参考:How to Show Custom Domain Name With Firebase Authentication Using Google?