当前位置: 首页 > 工具软件 > BigPicture.js > 使用案例 >

Vue.js和Node.js之间的Google Firebase身份验证

越勇
2023-12-01

Save a lot of manual digging, read this.

节省大量的手工挖掘工作,请​​仔细阅读。

So, what are we trying to do today?

那么,我们今天要做什么?

We’re going to build a Vue.js app and a Node.js app serving as frontend and backend for a web project. The user can log in on the frontend with Firebase Authenticate, using his Google, Facebook, Twitter, Github or whatever other account he has. The backend will detect the login, validate it, and allow the user to access the backend as a registered user.

我们将构建一个Vue.js应用程序和一个Node.js应用程序,用作Web项目的前端和后端。 用户可以使用他的Google,Facebook,Twitter,Github或他拥有的任何其他帐户,使用Firebase Authenticate登录到前端。 后端将检测登录,对其进行验证,并允许用户以注册用户的身份访问后端。

This tutorial may be useful even if you work with some other frontend framework or backend engine. Google’s service works pretty much the same way on every platform, so if you’re into, say, Java and Python, or you’re working on a mobile app and not a website, the process and the methods will be still pretty much the same.

即使您使用其他前端框架或后端引擎,本教程也可能会很有用。 Google的服务在每个平台上的工作方式几乎都是相同的,因此,如果您使用的是Java和Python,或者您正在使用移动应用程序而不是网站,则流程和方法仍然几乎可以相同。

The OAuth2 login mechanism, a short overview

OAuth2登录机制,简要概述

You perhaps already know how OAuth technology works, but if you don’t, here’s a quick rundown.

您可能已经知道OAuth技术的工作原理,但是如果您不了解,这将是一个快速的总结。

Once upon a time we used password authentication for websites, meaning that for every single project you had to implement the forms, the verification mechanism, maintain a user database, etc. OAuth brought a major change. Now you can use your account from some major online service to log in to other websites. Google Firebase allows you to enable such functionality in your project, eliminating the need for writing your own authentication engine. The downside is that you’ll have to rely on some shady big bad company. If you dislike that, you can use OpenId which is pretty much the same thing, but (allegedly) free of all this New World Order shit.

以前,我们对网站使用密码身份验证,这意味着对于每个项目,您都必须实现表单,验证机制,维护用户数据库等。OAuth带来了重大变化。 现在,您可以通过一些主要的在线服务使用您的帐户登录其他网站。 Google Firebase允许您在项目中启用此类功能,而无需编写自己的身份验证引擎。 缺点是,您将不得不依靠一些阴暗的大型坏公司。 如果您不喜欢这种方式,则可以使用几乎相同的OpenId ,但是(据说)没有所有这些《新世界秩序》。

The login process with these authentication agents is the following. You click a button on the website. A popup window appears, or you’re redirected to another page (you can choose which method to implement) where Google takes control and shows the login options. If you wanted Google authentication, it’ll be Google’s login interface, if you chose Facebook, Twitter or others, it’ll be theirs. They’re all handled by Google, you don’t have to implement a connection to every single authentication provider (although you can if you wish).

这些身份验证代理的登录过程如下。 您单击网站上的按钮。 出现一个弹出窗口,或将您重定向到另一个页面(您可以选择实现的方法),Google可以控制并显示登录选项。 如果您想要Google身份验证,它将是Google的登录界面,如果您选择Facebook,Twitter或其他,则将是他们的。 它们全都由Google处理,您不必实现与每个身份验证提供程序的连接(尽管您可以根据需要)。

When the user finished logging in, the agent returns control to your website either by closing the popup or navigating to a callback page. Then you’ll receive information about the user’s account like his name, email address, profile photo, and a lot more as a JSON structure. It’s called a JWT or JSON Web Token. Among this information is the authentication token. It’s a long, seemingly random string. You’ll have to pass this to your backend. It can be sent as POST data to https://your.site/login.

当用户完成登录后,代理会通过关闭弹出窗口或导航到回调页面来将控制权返回给您的网站。 然后,您将以JSON结构的形式接收有关用户帐户的信息,例如用户名,电子邮件地址,个人资料照片等。 它称为JWT或JSON Web令牌。 在此信息中是认证令牌。 这是一个长字符串,看似随机。 您必须将其传递给后端。 可以将其作为POST数据发送到https://your.site/login

When the backend receives this string, it connects to the provider and requests validation of the token. Basically it asks Google: “Hey, do you know this guy? Is he legit?” Then Google responds: “Yup, he’s legit, and here’s his name, email, profile picture, etc.” After this response you can accept this user’s login, or register him as a new user, and so on.

当后端收到此字符串时,它将连接到提供程序并请求验证令牌。 基本上,它会问Google: “嘿,你认识这个人吗? 他合法吗?” 然后Google回应: “是的,他是合法人,这是他的名字,电子邮件,个人资料图片等。” 在此响应之后,您可以接受该用户的登录,或将其注册为新用户,依此类推。

Then you can start a HTTP session, and from this point the backend will recognize the frontend until the session expires or the user logs out and terminates it.

然后,您可以启动HTTP会话,从这一点开始,后端将识别前端,直到会话过期或用户注销并终止它为止。

This method is way more secure than submitting passwords the old-fashioned way. The user can leverage all of Google’s advanced security features to keep his account safe, and you don’t have to worry about some bastard sniffing out network traffic. Google provides not only the service, but also officially supported libraries to implement everything both on the frontend and the backend.

这种方法比以老式方式提交密码更安全。 用户可以利用Google的所有高级安全功能来保护自己的帐户安全,而您不必担心某些杂种会窃听网络流量。 Google不仅提供服务,而且还提供正式支持的库以实现前端和后端的所有功能。

The only drawback is that it’s a little bit complicated at first sight. Not because it’s really complicated, but there’s a lack of concise examples on how to implement a simple login feature which most projects need. Most of us who figured it out often spent long days trying to understand Google’s inconsistent lingo and cross-referencing manuals. But cheers, here I am to help you out!

唯一的缺点是乍一看有点复杂。 不是因为它真的很复杂,而是缺少有关如何实现大多数项目所需的简单登录功能的简洁示例。 我们大多数弄清楚了这一点的人通常都花了很长时间试图理解Google不一致的术语和交叉引用手册。 但是,加油,我在这里为您提供帮助!

Step 1: Create the application

步骤1:建立应用程式

Go to https://console.firebase.google.com and create your project, or open an existing one to add Firebase Authentication.

转到https://console.firebase.google.com并创建您的项目,或打开一个现有项目以添加Firebase身份验证。

On the left side panel click Authentication, then on the Sign-in Method panel choose what kind of authentication would you like to implement. Apart from various third party services there’s also Email/Password, but it requires the implementation of the sign-in form and handle things like confirmation, password reset, etc. There’s also anonymous login.

在左侧面板上单击“ 身份验证”,然后在“ 登录方法”面板上选择要实施的身份验证类型。 除了各种第三方服务之外,还有电子邮件/密码,但它需要实现登录表单并处理诸如确认,密码重置等操作。还存在匿名登录。

When you choose a third party authentication service, you will have to configure the app not only on Firebase’s console, but also at the partner’s own control panel. Facebook, Twitter, Github and the rest all have their own API to handle authentication and other connections. It would go beyond the scope of this document to describe how to configure every single service, but I can assure you it’s a fairly easy process for most of them. You’re going to need a user account at each of the selected partners too. To keep this tutorial simple, I’m going to assume we’re only adding Google authentication. So just enable Google.

选择第三方身份验证服务时,您不仅需要在Firebase的控制台上配置应用程序,还必须在合作伙伴自己的控制面板上配置该应用程序。 Facebook,Twitter,Github和其他所有人都有自己的API来处理身份验证和其他连接。 描述如何配置每项服务将超出本文档的范围,但是我可以向您保证,对于大多数服务而言,这是一个相当简单的过程。 您还将在每个选定的合作伙伴处都需要一个用户帐户。 为了简化本教程,我假设我们仅添加Google身份验证。 因此,只需启用Google。

A Web Client ID and a Web Client Secret token will appear. That’s great, but we won’t need them.

将显示一个Web客户 端ID和一个Web客户端密钥 。 很好,但是我们不需要它们。

We’re now ready to implement our frontend authentication. We’ll return to the Firebase Console later, so you may want to leave the tab open.

现在,我们准备实现前端身份验证。 稍后我们将返回Firebase控制台,因此您可能需要使选项卡保持打开状态。

Step 2: The frontend part

步骤2:前端部分

Google provides some vanilla JavaScript snippets, but even better, there are officially supported wrappers for all major frameworks, including Vue.js. Of course Firebase can do much more than just authentication, and so can these add-ons.

Google提供了一些原始JavaScript代码段,但更好的是,所有主要框架(包括Vue.js)都得到了官方支持的包装器。 当然,Firebase不仅可以执行身份验证,还可以做更多的事情。

Adding VueFire and Firebase to your project is as easy as this:

VueFire和Firebase添加到您的项目就像这样简单:

npm i vuefire firebase

Then add this to your main.ts:

然后将其添加到您的main.ts

import { firestorePlugin } from 'vuefire';Vue.use(firestorePlugin);

That’s all. Now let’s add a Google Sign-in button to our app.

就这样。 现在,我们将Google登录按钮添加到我们的应用中。

First let’s create a JSON file called firebase.json where our Firebase defaults will be kept. What goes into this file? Open Firebase Console, click Project Overview, and scroll down on the General tab. You’ll find a Firebase SDK snippet there. Inside is a JSON structure, marked as Your web app’s Firebase configuration. Copy and paste this into the JSON file. It should look something like this:

首先,我们创建一个名为firebase.json的JSON文件,其中将保留我们的Firebase默认设置。 这个文件有什么内容? 打开Firebase控制台,单击“ 项目概述” ,然后在“ 常规”选项卡上向下滚动。 您将在此处找到Firebase SDK片段 。 里面是一个JSON结构,标记为您的Web应用程序的Firebase配置 。 将其复制并粘贴到JSON文件中。 它看起来应该像这样:

{
apiKey: "xxx",
authDomain: "xxx.firebaseapp.com",
databaseURL: "https://xxx.firebaseio.com",
projectId: "xxx",
storageBucket: "xxx.appspot.com",
messagingSenderId: "1091091352725",
appId: "1:1091091352725:web:xxx",
measurementId: "G-xxx"
}

Now we can create our Vue component:

现在我们可以创建我们的Vue组件:

import Firebase from 'firebase';
import * as firebaseConfig from "./firebase.json";@Component({})export default class Login extends Vue { private app; created() {
if (!Firebase.apps.length)
this.app = Firebase.initializeApp(firebaseConfig);
}
}

This creates a Firebase instance. Why the condition? It is because the instance can be created only once during a session. If it already exists, an exception will be thrown. This will happen even when we modify our code, and the app is refreshed in the browser because app-level dependencies aren’t refreshed.

这将创建一个Firebase实例。 为什么病情? 这是因为该实例在会话期间只能创建一次。 如果已经存在,则将引发异常。 即使我们修改了代码,并且由于未刷新应用程序级别的依赖关系而在浏览器中刷新了应用程序,也会发生这种情况。

Here we get to the first tricky part. Don’t worry, it’s not that tricky.

在这里,我们进入第一个棘手的部分。 不用担心,它不是那么棘手。

What we initialize here is an instance of the global Firebase object. It will persist throughout the app. Upon initialization, Firebase automatically assigns a name to the instance, which is always [DEFAULT] if you don’t specify another. The condition is to prevent reinitialization when one app instance already exists, causing an exception.

我们在这里初始化的是全局Firebase对象的实例。 它会在整个应用程序中持续存在。 初始化后,Firebase会自动为实例分配一个名称,如果您未指定其他名称,则始终为[DEFAULT] 。 条件是防止在一个应用程序实例已经存在时引发异常的情况下进行重新初始化。

Naming is only necessary when you need more than one instances, but that isn’t likely unless you’re writing some really big application. In that case every time you call a Firebase function, you’ll also have to specify which instance are you trying to talk to, or Firebase will assume you’re addressing [DEFAULT]. If you want to give the instance a name, it’s this simple:

仅当您需要多个实例时才需要命名,但是除非您正在编写一些非常大的应用程序,否则命名是不可能的。 在这种情况下,每次调用Firebase函数时,您还必须指定您要与之对话的实例,否则Firebase会假定您正在处理[DEFAULT] 。 如果要给实例命名,就这么简单:

this.app = Firebase.initializeApp(firebaseConfig, 'My Instance');

Now we have the instance, but it doesn’t do anything. Add a button or something to your template, and bind the @click event to this function:

现在我们有了实例,但是它什么也没做。 在模板中添加按钮或其他东西,然后将@click事件绑定到此函数:

public firebaseLogin() {  const provider = new Firebase.auth.GoogleAuthProvider();  Firebase.auth().signInWithPopup()
.then(async user => { let idToken;
await Firebase.auth().currentUser.getIdToken(true)
.then(res => idToken = res); console.log(idToken); })
}

The signInWithPopup() function will open the Google sign-in agent in a browser popup modal. To use Facebook, Twitter or other providers, you should change the value of provider to the appropriate authentication provider like Firebase.auth.FacebookAuthProvider().

signInWithPopup()函数将以浏览器弹出模式打开Goog​​le登录代理。 要使用Facebook,Twitter或其他供应商,您应的值更改provider像适当的认证提供Firebase.auth.FacebookAuthProvider()

The function is asynchronous and we await the retrieval of the token because we’ll send it to the backend when it’s retrieved. Replace the console output with the backend call (using Axios for example) to pass the token. The frontend part is now done!

该函数是异步的,我们await令牌的检索,因为检索到令牌后会将其发送到后端。 将控制台输出替换为后端调用(例如,使用Axios)以传递令牌。 前端部分现已完成!

Step 3: The backend part

步骤3:后端部分

Let’s assume you already have a Node.js app with Express up and running. You’ll need to addfirebase-admin.

假设您已经有一个运行Express的Node.js应用程序。 您需要添加firebase-admin

npm install firebase-admin --save

Verifying a token needs a little bit more trickery than logging in. First, go to Firebase Console again, click the gear icon, and go to Service Accounts.

验证令牌比登录需要更多的技巧。首先,再次转到Firebase控制台,单击齿轮图标,然后转到“ 服务帐户”。

Here you’ll see another configuration snippet for Node.js, Java, Python and Go. It’s not the code you’re looking for (as we’re obviously using Typescript). Click the Create new private key button. You’ll get some JSON data again, containing a private key and some other information. Put this into a separate JSON file, but NOT IN YOUR PROJECT DIRECTORY!!

在这里,您将看到针对Node.js,Java,Python和Go的另一个配置代码段。 这不是您要查找的代码(因为我们显然在使用Typescript)。 单击创建新的私钥按钮。 您将再次获得一些JSON数据,其中包含一个私钥和一些其他信息。 将此放入一个单独的JSON文件中,但不要放在您的项目目录中!

Why not? Well, it’s called private key for a reason. This is your app’s unique identification, a fingerprint if you prefer. Anyone can attempt a login to your app, meaning to tell an OAuth sign-in partner that he wants to get in. But the OAuth partner will only offer validation if your app is asking. In other words, anyone can leave a message for you at the post office, but they’ll only deliver them to you, upon presenting proper identification. If you put the JSON into your project directory, it may get pushed into your repository and leaked.

为什么不? 好吧,有一个原因称它为私钥。 这是您应用的唯一标识,如果您愿意,可以使用指纹。 任何人都可以尝试登录到您的应用程序,这意味着告诉OAuth登录合作伙伴他想进入。但OAuth合作伙伴仅在您的应用程序要求时提供验证。 换句话说,任何人都可以在邮局为您留言,但只有在出示适当的身份证明后,他们才会将其发送给您。 如果将JSON放入项目目录,则可能会将其推送到存储库中并泄漏。

The best way to handle this JSON is to store it in a dedicated directory on your server, inaccessible from the outside, but accessible for Node.js to read. I usually create a configuration JSON file for my apps and read the path to the secret file from there.

处理此JSON的最佳方法是将其存储在服务器上的专用目录中,该目录无法从外部访问,但可以供Node.js读取。 我通常为我的应用程序创建一个配置JSON文件,并从那里读取秘密文件的路径。

Here’s how you validate the token:

验证令牌的方法如下:

import * as admin from 'firebase-admin';const googleSecret = require('c:\secret\google.json');verifyToken(token) {
const serviceAccount = googleSecret;

if (!admin.apps.length)
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "xxx.firebaseio.com"
});
}

The databaseURL value came from that JavaScript snippet on the Firebase Console which I suggested you to ignore. This is the exact same Firebase instance initialization as on the frontend.

databaseURL值来自Firebase控制台上的该JavaScript代码段,我建议您忽略它。 这是与前端完全相同的Firebase实例初始化。

Actual verification is a breeze now. Assuming we have the token from the frontend in a variable named token:

现在,进行实际验证变得轻而易举。 假设我们在一个名为token的变量中拥有来自前端的token

admin.auth().verifyIdToken(token)
.then(user => {
console.log(user);
});

And boom! The login is verified. You can store the data, request the user’s full profile or anything. It’s a good idea to start a session and save the user’s name, user ID and perhaps email address for further reference.

和繁荣! 登录名已验证。 您可以存储数据,请求用户的完整个人资料或其他任何内容。 启动会话并保存用户名,用户ID以及可能的电子邮件地址,以供进一步参考是一个好主意。

翻译自: https://medium.com/developer-rants/google-firebase-authentication-between-vue-js-and-node-js-7ed3568a0c60

 类似资料: