使用 Firestore 处理会话

许多应用需要处理身份验证和用户偏好设置的会话。Node.js Express 框架附带基于内存的实现可实现此功能。但此实现不适用于可以通过多个实例提供的应用,因为各实例之间记录的会话可能不同。本教程介绍如何在 App Engine 上处理会话。

目标

  • 编写应用。
  • 在本地运行应用。
  • 在 App Engine 上部署应用。

费用

本教程使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用量来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册一个新帐号

  2. 在 Cloud Console 的项目选择器页面上,选择或创建 Cloud 项目。

    转到项目选择器页面

  3. 确保您的 Google Cloud 项目已启用结算功能。 了解如何确认您的项目已启用结算功能

  4. 启用 Firestore API。

    启用 API

  5. 安装并初始化 Cloud SDK

设置项目

  1. 在终端窗口中,从您选择的目录启动,并创建一个名为 sessions 的新目录。本教程的所有代码均位于 sessions 目录内。

  2. 切换到 sessions 目录:

    cd sessions
    
  3. 初始化 package.json 文件:

    npm init .
    
  4. 安装依赖项:

    npm install \
     --save @google-cloud/connect-firestore @google-cloud/firestore express express-session
    

在本教程结束时,最终文件结构类似于以下内容:

sessions
├── app.yaml
├── index.js
└── package.json

编写 Web 应用

此应用为每位用户显示不同语言的问候语。回访用户始终会收到同一种语言的问候语。

多个应用窗口显示不同语言的问候语。

在应用存储用户偏好设置之前,您需要存储会话中当前用户的相关信息。此示例应用使用 Firestore 来存储会话数据。

您可以使用与 express-session 兼容的会话存储 connect-firestore

  • 在终端窗口中,使用以下内容创建名为 index.js 的文件:

    // Copyright 2019, Google LLC.
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //    http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    
    const {Firestore} = require('@google-cloud/firestore');
    const express = require('express');
    const session = require('express-session');
    
    const app = express();
    const {FirestoreStore} = require('@google-cloud/connect-firestore');
    
    app.use(
      session({
        store: new FirestoreStore({
          dataset: new Firestore({
            kind: 'express-sessions',
          }),
        }),
        secret: 'my-secret',
        resave: false,
        saveUninitialized: true,
      })
    );
    
    const greetings = [
      'Hello World',
      'Hallo Welt',
      'Ciao Mondo',
      'Salut le Monde',
      'Hola Mundo',
    ];
    
    app.get('/', (req, res) => {
      if (!req.session.views) {
        req.session.views = 0;
        req.session.greeting =
          greetings[Math.floor(Math.random() * greetings.length)];
      }
      const views = req.session.views++;
      res.send(`${views} views for ${req.session.greeting}`);
    });
    
    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log(`Example app listening on port ${port}!`);
    });
    
    module.exports = app;
    

下图说明了 Firestore 如何处理 App Engine 应用的会话。

架构图:用户、App Engine、Firestore。

设置 app.use(session) 之后,每个请求都有一个 req.session 属性用于标识周期性用户。会话数据存储在 Firestore 中。

删除会话

Connect-firestore 不会删除旧的或已过期的会话。您可以在 Google Cloud Console删除会话数据,或实施自动删除策略。如果您为会话使用 Memcache 或 Redis 等存储解决方案,系统会自动删除已过期的会话。

在本地运行

  1. 在终端窗口中,安装 Google Cloud 项目的依赖项:

    npm install
    
  2. 启动 HTTP 服务器:

    npm start
    
  3. 查看网络浏览器中的应用:

    Cloud Shell

    在 Cloud Shell 工具栏中,点击 Web 预览 Web 预览,然后选择在端口 8080 上预览

    本地机器

    在浏览器中,转到 http://localhost:8080

    您会看到五个问候语之一:“Hello World”、“Hallo Welt”、“Hola mundo”、“Salut le Monde”或“Ciao Mondo”。如果您使用其他浏览器或无痕模式打开网页,语言会更改。您可以在 Google Cloud Console 中查看和修改会话数据。

    Cloud Console 中的 Firestore 会话。

  4. 要停止 HTTP 服务器,请在终端窗口中按 Control+C

在 App Engine 上部署并运行

通过 App Engine 标准环境,您可以构建和部署在繁重负载和大量数据的压力下仍能可靠运行的应用。

本教程使用 App Engine 标准环境来部署服务器。

  1. 在您的终端窗口中,创建一个 app.yaml 文件并复制以下内容:

    runtime: nodejs10
  2. 在 App Engine 上部署应用:

    gcloud app deploy
    
  3. 输入以下网址,查看正在运行的应用:

    https://PROJECT_ID.REGION_ID.r.appspot.com

    替换以下内容:

现在,问候语由在 App Engine 实例上运行的 Web 服务器提供。

调试应用

如果您无法连接到 App Engine 应用,请检查以下内容:

  1. 检查 gcloud 部署命令是否已成功完成,并且未输出任何错误。如果存在错误(例如 message=Build failed),修复问题,然后再次尝试部署 App Engine 应用
  2. 在 Cloud Console 中,转到日志查看器页面。

    转到“日志查看器”页面

    1. 最近选择的资源下拉列表中,点击 App Engine 应用,然后点击所有 module_id。您将看到访问您的应用时的请求列表,如果您未发现请求列表,请确认您是否已从下拉列表中选择所有 module_id。如果您发现 Cloud Console 出现错误消息,请检查应用代码是否与“编写 Web 应用”相关部分中的代码匹配。

    2. 确保已启用 Firestore API。

清理

删除项目

  1. 在 Cloud Console 中,转到管理资源页面。

    转到“管理资源”页面

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除 App Engine 实例

  1. 在 Cloud Console 中,转到 App Engine 的版本页面。

    转到“版本”页面

  2. 选中要删除的非默认应用版本对应的复选框。
  3. 点击删除 以删除应用版本。

后续步骤