使用Sapper Firebase进行身份验证

While it's great to work with Firebase and Sapper separately, joining these two can be a bit of a hassle. It took me a few days to figure out how to implement an authentication system with Firebase and Sapper which met the following criteria:

单独使用Firebase和Sapper固然很棒,但将两者结合起来可能会有些麻烦。 我花了几天的时间弄清楚如何使用Firebase和Sapper满足以下条件的身份验证系统:

  • No flash of content (due to redirects or page protections).

    没有内容闪烁(由于重定向或页面保护)。

  • Protected routes are still available when an authenticated user refreshes the page.

    当经过身份验证的用户刷新页面时,受保护的路由仍然可用。

  • SSR (server-side rendering) still works when the firebase token expires and refreshes.

    当Firebase令牌过期并刷新时,SSR(服务器端呈现)仍然有效。

This tutorial will be barebone and quick since I myself don't like long fancy tutorials. So strap in and learn with me.

由于我本人不喜欢冗长的教程,因此该教程将成为准系统且快速。 因此,请与我一起学习。

步骤0:安装Sapper (Step 0: Sapper installation)

Let's start by creating a default Sapper project. I called this project 'firebase-sapper-synergy', and after the installation, go into the folder and install all the dependencies (yarn install). When that is finished, run the development environment via yarn dev and go to http://localhost:3000/ in your browser.

首先创建一个默认的Sapper项目。 我将此项目称为“ firebase-sapper-synergy ”,安装后,进入文件夹并安装所有依赖项( yarn install )。 完成后,通过yarn dev运行开发环境,然后转到 浏览器中的http:// localhost:3000 /

npx degit "sveltejs/sapper-template#rollup" firebase-sapper-synergy
cd firebase-sapper-synergy
yarn install
yarn dev
Image for post
Your sapper-project running on http://localhost:3000/
您的sapper-project在http:// localhost:3000 /上运行

步骤1:建立登入表格和(即将受到保护)资讯主页 (Step 1: Create a login-form & (soon to be protected) dashboard page)

Delete the /src/routes/blog/* folder and the about.svelte page, since we won't be needing them. Add two new empty/blank pages inside the/src/routes/ folder named: dashboard.svelte and login.svelte. Go to the Nav-component inside /src/components/ and add the new pages to it.

删除/ src / routes / blog / *文件夹和about.svelte页面,因为我们不需要它们。 在/ src / routes /文件夹内添加两个新的空白页,分别为: dashboard.sveltelogin.svelte 。 转到/ src / components /中的Nav-component并将新页面添加到其中。

Nav component
导航组件

步骤2:保护仪表板页面 (Step 2: Secure the dashboard page)

You should be able to freely navigate between all the (empty) pages. Let's protect our dashboard.svelte for unauthorized access:

您应该能够在所有(空白)页面之间自由导航。 保护我们的dashboard.svelte ,防止未经授权的访问:

Firstly, we use the sapper.middleware() to populate our Sapper store/session when a user connects to the server. This needs to be done in server.js.

首先,当用户连接到服务器时,我们使用sapper.middleware()填充Sapper存储/会话。 这需要在server.js中完成。

Sapper.middleware added (don't forget to restart the server)
添加了Sapper.middleware(不要忘记重新启动服务器)

To protect our dashboard.svelte (without flashing when redirected), we need to check if a user exists BEFORE we render/see the page. Luckily, Sapper has a nice little function called preload(), that will load some data that the page depends on before it renders it. We check the current user session inside this preload-function and decide if we redirect the user or not. Currently, the user is always false (set by our middleware) and the user will be redirected to the (empty) login page.

为了保护我们的dashboard.svelte (重定向时不闪烁),我们需要在呈现/查看页面之前检查用户是否存在。 幸运的是,Sapper有一个不错的小函数preload() ,它将在呈现页面之前加载页面依赖的一些数据。 我们检查此preload-function中的当前用户会话,并确定是否重定向用户。 当前,用户始终为假(由我们的中间件设置),并且该用户将被重定向到(空)登录页面。

Protecting our dashboard page by checking if a user exists (which is always false at the moment)
通过检查用户是否存在来保护我们的信息中心页面(此刻始终为假)

步骤3:根据Firebase身份验证填充用户会话 (Step 3: Populating our user session, based on Firebase Authentication)

You should already have a Firebase project setup on https://console.firebase.google.com together with the firebaseClient API configuration values and Firebase Authentication enables. Take a look at this guide, if you don’t know what I’m talking about.

您应该已经在 https://console.firebase.google.com 上具有Firebase项目设置, 以及firebaseClient API配置值和Firebase身份验证启用。 如果您不知道我在说什么, 请看一下 本指南

So now we need to log in a user with firebase, save it to our store/session and remember this user when a page is refreshed manually (client AND server-side). Add the Firebase client SDK via a CDN in the template.html (just before the </body> tag:

因此,现在我们需要使用firebase登录用户,将其保存到我们的存储/会话中,并在手动刷新页面(客户端和服务器端)时记住该用户。 通过CDN在template.html中添加Firebase客户端SDK(位于</ body>标记之前:

This enables us to use the Firebase Authentication service inside our app. Create an e-mail & password field inside our login.svelte page, together with a button with an onClick event called login(). This login-function will call our Firebase Authentication service and if successful redirects us to the dashboard:

这使我们能够在应用程序内使用Firebase身份验证服务。 在我们的login.svelte页面内创建一个电子邮件和密码字段,以及一个带有名为click ()的onClick事件的按钮 此登录功能将调用我们的Firebase身份验证服务,如果成功,则会将我们重定向到仪表板:

Valid login credentials still redirect you back to the login page, because we don't change the user in the session/store. firebase.auth().onIdTokenChanged() can help us with keeping the logged-in user in sync with our own session/store. Add onIdTokenChanged() In our _layout.svelte page, inside a onMount() function. onMount() is needed because we can only access onIdTokenChanged() on the client-side. When the user logs in, onIdTokenChanged() is triggered and sets the user in the session/store. If you go to your localhost, you can now login en go to the dashboard!

有效的登录凭据仍会将您重定向到登录页面,因为我们不会在会话/存储中更改用户。 firebase.auth()。onIdTokenChanged()可以帮助我们使登录用户与我们自己的会话/存储保持同步。 在我们的_layout.svelte页面的onMount()函数内添加onIdTokenChanged() 。 需要onMount()是因为我们只能在客户端访问onIdTokenChanged()。 用户登录时,将触发onIdTokenChanged()并将其设置为会话/存储中的用户。 如果您转到本地主机,则现在可以登录zh进入仪表板!

You can add a logout button to the dashboard and see that it is protected again when you log out:

您可以在仪表板上添加一个注销按钮,并在注销时看到它再次受到保护:

步骤4:将使用者的凭证储存为Cookie (Step 4: Saving the user's token as a cookie)

So we got an authentication service, with a protected route when the user is not logged in. There is only one problem; when you refresh the page when you are at /dashboard, you will get redirected back to /login. Why? Doesn't Firebase keep a session active for you in the browser?

因此,我们获得了身份验证服务,当用户未登录时,该服务具有受保护的路由。 在/ dashboard上刷新页面时,您将被重定向回/ login 。 为什么? Firebase不会在浏览器中为您保持活动状态吗?

It does, but before we detect a user on a refresh, preload() already checked for a user and can't find one because the onIdTokenChanged() is not fast enough to set the user in the store/session and allow access to /dashboard. We can prevent this unwanted redirect on refresh, by setting the store when the user requests the page.

可以,但是在我们检测到刷新用户之前, preload ()已经检查了一个用户,并且找不到它,因为onIdTokenChanged ()不够快,无法在存储/会话中设置该用户并允许访问/仪表板 。 我们可以通过在用户请求页面时设置存储来防止刷新时发生这种不必要的重定向。

First, install a client-side cookie library to set/get cookies. I picked js-cookie: yarn add js-cookie and after that adjust the code inside onIdTokenChanged() to save a cookie every time a user is logged in/out:

首先,安装客户端cookie库以设置/获取cookie。 我选择了js-cookie: yarn add js-cookie ,然后在onIdTokenChanged()中调整代码以在每次用户登录/注销时保存cookie:

Now we need to check on the server-side if there is a cookie (with a user token) on each request and populate the session with it. Again, install a cookie-parser for our server-side: yarn add cookie-parser

现在,我们需要在服务器端检查每个请求上是否有一个cookie(带有用户令牌),并在其中填充会话。 再次,为我们的服务器端安装一个cookie解析器: yarn add cookie-parser

Important note: you now have a protected route with a login page, without flashes of content and its server-side rendered when needed, all working together with Firebase! However, there is one gotcha… the token you generated for a user (and set as the cookie) is only valid for 1 hour. After that hour the Firebase client silently refreshes the user token. This refresh does not get picked up by our onIdTokenChanged() listener and thus our new token is not set as a cookie. This could eventually cause errors. We can use the .getIdToken(true) function to manually reset the token every 55 minutes (and which triggers our onIdTokenChanged()). Just place a setTimeout() with a function that checks if we have an active user and refreshes the token if we do. This is a recurring function along as we have a user that's logged in.

重要说明:您现在有了带有登录页面的受保护路由,没有内容闪烁,并且在需要时呈现了服务器端,所有这些都与Firebase一起使用! 但是,有一个陷阱……您为用户生成的令牌(并设置为cookie)仅有效1个小时。 一小时后,Firebase客户端会静默刷新用户令牌。 我们的onIdTokenChanged()侦听器不会进行此刷新,因此我们的新令牌未设置为cookie。 最终可能导致错误。 我们可以使用。 getIdToken ( true )函数每隔55分钟手动重置令牌(并触发我们的onIdTokenChanged()) 。 只需将setTimeout()与函数一起检查我们是否有活动的用户,如果有则刷新令牌。 这是一个循环功能,并且有一个已登录的用户。

摘要 (Summary)

So there you have it! I wanted to show you a simple way of using Sapper with Firebase. It does not cause any flashes of content and works great with the server-side of Sapper. You can build upon this and might use the Firebase Admin SDK on the server-side to check incoming tokens and/or get the users data from Firestore. Let me know if everything works for you!

所以你有它! 我想向您展示一种将Sapper与Firebase结合使用的简单方法。 它不会引起任何内容闪烁,并且非常适合Sapper的服务器端。 您可以以此为基础,并可以在服务器端使用Firebase Admin SDK来检查传入令牌和/或从Firestore获取用户数据。 让我知道一切是否适合您!

翻译自: https://medium.com/swlh/authentication-with-sapper-firebase-d3b060ad30e5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值