From a696ee773c63ad22fa33aeb5cbdcb012f0982fb9 Mon Sep 17 00:00:00 2001 From: Xingyu Wang Date: Tue, 12 Dec 2023 11:10:39 +0800 Subject: [PATCH] RP @Drwhooooo https://linux.cn/article-16462-1.html --- ...⭐️⭐️ Build your own SaaS on Linux with Vely.md | 202 +++++++++--------- 1 file changed, 104 insertions(+), 98 deletions(-) rename {translated/tech => published}/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md (64%) diff --git a/translated/tech/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md b/published/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md similarity index 64% rename from translated/tech/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md rename to published/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md index 3d076a9ae2..1ae8d548fc 100644 --- a/translated/tech/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md +++ b/published/20221107.2 ⭐️⭐️⭐️ Build your own SaaS on Linux with Vely.md @@ -3,25 +3,27 @@ [#]: author: "Sergio Mijatovic https://opensource.com/users/vely" [#]: collector: "lkxed" [#]: translator: "Drwhooooo" -[#]: reviewer: " " -[#]: publisher: " " -[#]: url: " " +[#]: reviewer: "wxy" +[#]: publisher: "wxy" +[#]: url: "https://linux.cn/article-16462-1.html" 利用 Vely 在 Linux 构建你自己的 SaaS ====== -Vely 语言使得 C 语言在你的 Web 应用程序中得到充分利用这件事成为可能。 +![][0] -[Vely][1]将 C 语言的高性能和低内存占用与 PHP 等语言的易用性和安全性相结合。作为免费的开源软件,它受 GPLv3 和 LGPL 3 的许可,所以你甚至可以用它来构建商业软件。 +> Vely 可让你在网络应用程序中利用 C 语言的强大功能。 + +[Vely][1] 将 C 语言的高性能和低内存占用与 PHP 等语言的易用性和安全性相结合。作为自由开源软件,它以 GPLv3 和 LGPL 3 授权,所以你甚至可以用它来构建商业软件。 ### 利用 Vely 构建 SaaS -您可以使用 Vely 创建一个多租户 web 应用程序,它可以作为软件即服务模式(Software-as-a-Service, SaaS)在互联网上运行。每个用户都有一个完全独立的数据空间。 +你可以使用 Vely 创建一个多租户网络应用程序,它可以作为软件即服务模式(SaaS)在互联网上运行。每个用户都有一个完全独立的数据空间。 -在这个web应用程序示例中,用户可以注册一个笔记本服务来创建笔记,然后查看和删除它们。它在横跨7个源文件的310行代码中演示了几种技术集成。这些技术包括: +在这个网络应用程序示例中,用户可以注册一个笔记本服务来创建笔记,然后查看和删除它们。它仅用了 7 个源文件,310 行代码,就展示了如何集成多项技术: - MariaDB -- Web 浏览器 +- 网络浏览器 - Apache - Unix 套接字 @@ -59,11 +61,11 @@ Vely 语言使得 C 语言在你的 Web 应用程序中得到充分利用这件 #### 设置先决条件 -遵照[Vely.dev][9]上的安装指示。这是使用标准工具包的快速流程,例如 DNF,APT,Pacman 或者 Zypper。 +遵照 [Vely.dev][9] 上的安装指示。这是一个使用 DNF、APT、Pacman 或者 Zypper 等标准工具包的快速流程。 -这缘于他们都是这个范例的一部分,你必须安装 Apache 作为 web 服务器,安装 MariaDB 作为数据库。 +由于它们都是这个范例的一部分,你必须安装 Apache 作为网络服务器,安装 MariaDB 作为数据库。 -安装 Vely 后,使用 Vim 时,打开里面的“语法高亮显示”如果你在使用它的话: +安装 Vely 后,如使用 Vim,打开里面的“语法高亮显示”: ``` vv -m @@ -71,116 +73,116 @@ vv -m #### 获取源代码 -这个演示 SaaS 应用程序的源代码是 Vely 安装的一部分。为每个应用程序创建一个单独的源代码目录不失为一个好主意(而且你可以按自己喜好命名)。在这种情况下,解包源代码会帮你完成这些工作: +这个演示 SaaS 应用程序的源代码是 Vely 安装的一部分。为每个应用程序创建一个单独的源代码目录不失为一个好主意(而且你可以按自己喜好命名)。在这种情况下,解包源代码会帮你完成这些工作: ``` $ tar xvf $(vv -o)/examples/multitenant_SaaS.tar.gz $ cd multitenant_SaaS ``` -默认情况下,该应用程序以`multitenant_SaaS`命名,但你可以将其命名为任何内容(如果这么做,其他每个地方你都需要改一遍)。 +默认情况下,该应用程序以 `multitenant_SaaS` 命名,但你可以将其命名为任何内容(如果这么做,其他每个地方你都需要改一下)。 ### 创建应用程序 -第一步是创建一个应用程序。使用Vely的`vf`工具很简单: +第一步是创建一个应用程序。使用 Vely 的 `vf` 工具就可以轻松完成: ``` $ sudo vf -i-u $(whoami) multitenant_SaaS ``` -这个命令创建了一个新的应用程序主页(`/var/lib/vv/multitenant_SaaS`),并帮你执行应用程序设置。通常,这意味着在主文件夹中创建各种子目录并分配权限。在这种情况下,只有当前用户(`whoami`的结果)拥有目录,具有 0700 权限,这确保了其他人没有访问文件的权限。 +这个命令创建了一个新的应用程序主目录(`/var/lib/vv/multitenant_SaaS`),并帮你执行应用程序设置。通常,这意味着在该主目录中创建各种子目录并分配权限。在这种情况下,只有当前用户(`whoami` 的结果)拥有目录,具有 `0700` 权限,这确保了其他人没有访问文件的权限。 ### 创建数据库 -在你键入任何代码之前,你需要一个能够存储该应用程序所用信息的空间。首先,创建一个名为`db_multitenant_SaaS`的 MariaDB 数据库,由用户名`vely`密码`your_password`的用户所有。你可以修改刚才提到的任何数据,但得记住,在这个示例里,你需要将包含这些内容的每个地方都得修改一遍。 +在你键入任何代码之前,你需要一个能够存储该应用程序所用信息的空间。首先,创建一个名为 `db_multitenant_SaaS` 的 MariaDB 数据库,由用户名为 `vely` 的用户所有,密码为 `your_password` 。你可以修改刚才提到的任何值,但得记住,在这个示例里,你需要将包含这些内容的每个地方都得修改一遍。 在 MySQL 中以 root 身份登录: ``` -CREATEDATABASEIFNOTEXISTS db_multitenant_SaaS; -CREATEUSERIFNOTEXISTS vely IDENTIFIEDBY'your_password'; -GRANTCREATE,ALTER,DROP,SELECT,INSERT,DELETE,UPDATEON db_multitenant_SaaS.*TO vely; +create database if not exists db_multitenant_SaaS; +create user if not exists vely identified by 'your_password'; +grant create,alter,drop,select,insert,delete,update on db_multitenant_SaaS.* to vely; ``` 然后在数据库内创建数据库对象(表,记录等等): ``` -USE db_multitenant_SaaS; -SOURCE setup.sql; +use db_multitenant_SaaS; +source setup.sql; exit ``` ### 将 Vely 连接至数据库 -为了让 Vely 知晓你数据库的位置以及如何登录进去,创建一个名为`db_multitenant_SaaS`的数据库配置文件。(该名称用于在源代码中的数据库声明,所以如果你改了它,确保在它存在的每个地方都改一遍。) +为了让 Vely 知晓你数据库的位置以及如何登录进去,创建一个名为 `db_multitenant_SaaS` 的数据库配置文件。(该名称用于在源代码中的数据库声明,所以如果你改了它,确保在它存在的每个地方都改一遍。) Vely 使用原生的 MariaDB 数据库连接,因此你可以指定给定的数据库所能允许的任何选项: ``` -$ echo'[client] +$ echo '[client] user=vely password=your_password database=db_multitenant_SaaS protocol=TCP host=127.0.0.1 -port=3306'> db_multitenant_SaaS +port=3306' > db_multitenant_SaaS ``` ### 构建应用程序 -使用`vv`工具构建应用程序,利用`--db`选项指定 MariaDB 数据库和数据库配置文件: +使用 `vv` 工具构建应用程序,利用 `--db` 选项指定 MariaDB 数据库和数据库配置文件: ``` $ vv -q--db=mariadb:db_multitenant_SaaS ``` -### 启用应用程序服务器 +### 启用应用服务器 -启用你 web 应用程序的服务器,需要使用`vf`的 FastCGI 过程管理器。应用程序服务器使用 Unix 套接字与 web 服务器(创建反向代理)通信: +启动你的网络应用程序的服务器,需要使用 `vf` FastCGI 进程管理器。应用程序服务器使用 Unix 套接字与网络服务器(创建反向代理)通信: ``` $ vf -w3 multitenant_SaaS ``` -这么做会启用三个守护进程来服务传入的请求。你也可以启用自适应服务器,它会增加进程的数量从而服务更多的请求,并在不需要他们时减少进程的数量: +这么做会启用三个守护进程,为接收到的请求提供服务。你也可以启动一个自适应服务器,它会增加进程的数量从而服务更多的请求,并在不需要他们时减少进程的数量: ``` $ vf multitenant_SaaS ``` -查看`vf`中的更多帮助你获得最好性能的选项。 +请参阅 `vf` 了解更多选项,以帮助你实现最佳性能。 -当你需要停用你的应用程序服务器,使用`-m quit`选项: +当你需要停止你的应用程序服务器,使用 `-m quit` 选项: ``` $ vf -m quit multitenant_SaaS ``` -### 创建 web 服务器 +### 创建网络服务器 -这是一个 web 应用程序,那么应用程序就得需要一个 web 服务器。该示例通过一个 Unix 套接字监听器使用 Apache。 +这是一个网络应用程序,那么应用程序就得需要一个网络服务器。该示例通过一个 Unix 套接字监听器使用 Apache。 -#### 1. 设置 Apache +#### 1、设置 Apache -将 Apache 配置为一个反向代理并将你的应用程序与之连接,你需要启用 FastCGI 代理支持,这通常表示使用`proxy` 和 `proxy_fcgi` 模块。 +将 Apache 配置为一个反向代理,并将你的应用程序与之连接,你需要启用 FastCGI 代理支持,这通常使用 `proxy` 和 `proxy_fcgi` 模块。 -对于 Fedora 系统(或者其它的,比如 Arch)来说,通过添加(或取消注释)在 Apache 配置文件`/etc/httpd/conf/httpd.conf`中适当的 **加载模块** 指令,就可启用`proxy`和`proxy_fcgi`模块。 +对于 Fedora 系统(或者其它的,比如 Arch)来说,通过在 Apache 配置文件 `/etc/httpd/conf/httpd.conf` 中添加(或取消注释)适当的 `LoadModule` 指令,就可启用 `proxy` 和 `proxy_fcgi` 模块。 -以下指令适用于 Debian,Ubuntu 以及类似的系统,启用`proxy`和`proxy_fcgi`模块: +以下指令适用于 Debian,Ubuntu 以及类似的系统,启用 `proxy` 和 `proxy_fcgi` 模块: ``` $ sudo a2enmod proxy $ sudo a2enmod proxy_fcgi ``` -以下指令适用于 OpenSUSE,将这几行添加在`/etc/apache2/httpd.conf`结尾处: +以下指令适用于 OpenSUSE,将这几行添加在 `/etc/apache2/httpd.conf` 结尾处: ``` LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ``` -#### 2. 配置 Apache +#### 2、配置 Apache 现在你必须将代理信息添加在 Apache 的配置文件中: @@ -188,13 +190,13 @@ LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ProxyPass "/multitenant_SaaS" unix:///var/lib/vv/multitenant_SaaS/sock/sock|fcgi://localhost/multitenant_SaaS ``` -你们配置文件的位置可能会有所不同,这取决于你们不同的 Linux 发行版: +你的配置文件的位置可能会有所不同,这取决于不同的 Linux 发行版: -- Fedora,CentOS,Mageia 和 Arch: `/etc/httpd/conf/httpd.conf` -- Debian,Ubuntu,Mint: `/etc/apache2/apache2.conf` +- Fedora、CentOS、Mageia 和 Arch: `/etc/httpd/conf/httpd.conf` +- Debian、Ubuntu、Mint: `/etc/apache2/apache2.conf` - OpenSUSE:`/etc/apache2/httpd.conf` -#### 3. 重新启动 +#### 3、重新启动 最后,重启 Apache。在 Fedora 和类似系统,还有 Arch Linux 是如下指令: @@ -210,7 +212,7 @@ $ sudo systemctl restart apache2 ### 设置本地邮箱 -这个示例将电子邮件作为其功能的一部分。如果你的服务器已经可以发送电子邮件了,你可以跳过这一条。此外,你可以使用本地邮箱(`myuser@localhost`)来测试它。要做到这一点,需安装 Sendmail。 +这个示例中,电子邮件是其功能的一部分。如果你的服务器已经可以发送电子邮件了,你可以跳过这一条。此外,你可以使用本地邮箱(`myuser@localhost`)来测试它。要做到这一点,需安装 Sendmail。 在 Fedora 和类似系统中是如下指令: @@ -219,51 +221,51 @@ $ sudo dnf installsendmail $ sudo systemctl start sendmail ``` -而在 Debian 系统(像 Ubuntu): +而在 Debian 和类似系统(如 Ubuntu): ``` $ sudo apt installsendmail $ sudo systemctl start sendmail ``` -当应用程序向本地用户发送电子邮件,比如说`OS_user@localhost`,你就可以通过查看`/var/mail/`处(所谓“邮件池”)来确认电子邮件是否被发送。 +当应用程序向本地用户发送电子邮件,比如说 `OS_user@localhost`,你就可以通过查看 `/var/mail/` 处(即所谓“邮件池”)来确认电子邮件是否被发送。 -### 自浏览器访问应用程序服务器 +### 从浏览器访问应用服务器 -假设你在本地运行该应用程序,可以自你的 web 服务器通过使用`http://127.0.0.1/multitenant_SaaS?req=notes&action=begin`域名访问你的应用程序服务器。如果你再互联网的在线服务器运行该程序,你可能就需要调整防火墙设置以允许 HTTP 通信。 +假设你在本地运行该应用,可以通过使用 `http://127.0.0.1/multitenant_SaaS?req=notes&action=begin` 域名从你的网络服务器访问你的应用服务器。如果你在互联网上的在线服务器运行该程序,你可能就需要调整防火墙设置以允许 HTTP 通信。 ### 源代码 -该应用程序示例包含 7 个源文件。你可以自行回顾代码(记住,这些文件只有 310 行代码),不过这里有关于每个文件的概述。 +该应用程序示例包含 7 个源文件。你可以自行回顾代码(记住,这些文件只有 310 行代码),下面是每个文件的概述。 -#### SQL 设置 (setup.sql) +#### SQL 设置(setup.sql) 创建的两个表: -- **用户**:每个用户的信息。在 **users** 表中,每个用户都有自己唯一的 ID (**userId** 列),以及其他信息,如电子邮件地址和该地址是否通过验证。还有一个哈希密码。实际的密码永远不会存储在纯文本(或其他形式)中;单向哈希用于检查密码。 -- **笔记**:用户输入的笔记。**notes** 表包含了所有的笔记,每个笔记都有一个 **userId** 列,表示哪个用户拥有它们。**userId** 列的值与 **users** 表中的同名列匹配。这样,每个笔记显然都属于单个用户。 +- `users`:每个用户的信息。在 `users` 表中,每个用户都有自己唯一的 ID (`userId` 列),以及其他信息,如电子邮件地址和该地址是否通过了验证。还有一个哈希密码。实际的密码永远不会存储在纯文本(或其他形式)中,单向哈希用于检查密码。 +- `notes`:用户输入的笔记。`notes` 表包含了所有的笔记,每个笔记都有一个 `userId` 列,表示哪个用户拥有它们。`userId` 列的值与 `users` 表中的同名列匹配。这样,每个笔记显然都属于单个用户。 该文件内容如下: ``` -CREATETABLEIFNOTEXISTS notes (dateOf datetime, noteId BIGINTAUTO_INCREMENTPRIMARYKEY, userId BIGINT, note VARCHAR(1000)); -CREATETABLEIFNOTEXISTS users (userId BIGINTAUTO_INCREMENTPRIMARYKEY, email VARCHAR(100), hashed_pwd VARCHAR(100), verified SMALLINT, verify_token VARCHAR(30),SESSIONVARCHAR(100)); -CREATEUNIQUEINDEXIFNOTEXISTS users1 ON users (email); +create table if not exists notes (dateOf datetime, noteId bigint auto_increment primary key, userId bigint, note varchar(1000)); +create table if not exists users (userId bigint auto_increment primary key, email varchar(100), hashed_pwd varchar(100), verified smallint, verify_token varchar(30), session varchar(100)); +create unique index if not exists users1 on users (email); ``` -#### 运行时数据 (login.h) +#### 运行时数据(login.h) 为了正确地显示登录、注册和注销链接,你需要一些在应用程序中任何地方都可以使用的标志。此外,应用程序使用 cookie 来维护会话,因此它需要在任何地方都可用,例如,验证会话是否有效。发送到应用程序的每个请求都以这种方式进行确认。只有带有可验证 cookie 的请求是允许的。 -所以要做到这种效果,你需要有一个 **global_request_data** 类型的`reqdata`(请求数据)并且其中包含`sess_userId`(用户的 ID)以及`sess_id`(用户目前的会话 ID)。你还最好有具有自说明性的标志帮着呈现页面: +所以要做到这种效果,你需要有一个 `global_request_data` 类型的 `reqdata`(请求数据),其中包含 `sess_userId`(用户的 ID)以及 `sess_id`(用户目前的会话 ID)。此外,还有一些不言自明的标志,可以帮助渲染页面: ``` #ifndef _VV_LOGIN #define _VV_LOGIN typedef struct s_reqdata { -    bool displayed_logout; // true 如果显示登出连接 -    bool is_logged_in; // true 如果会话验证登录 +    bool displayed_logout; // true 则显示登出连接 +    bool is_logged_in; // true 则会话已验证登录     char *sess_userId; // 目前会话的用户 ID     char *sess_id; // 会话 ID } reqdata; @@ -273,23 +275,23 @@ void login_or_signup (); #endif ``` -#### 会话检查和会话数据 (_before.vely) +#### 会话检查和会话数据(_before.vely) -Vely 里有一个 **before_request_handler** 的概念。你写的代码是在任何处理请求的代码之前执行的。要达到这个目的,你只需要将这样的代码写在名为`_before.vely`的文件中,然后剩余的部分将会自动处理。 +Vely 里有一个 请求前处理程序before_request handler 的概念。你写的代码会在其它处理请求的代码之前执行的。要达到这个目的,你只需要将这样的代码写在名为 `_before.vely` 的文件中,然后剩余的部分将会自动处理。 -任何 SaaS 应用程序所能作的,例如处理发送至应用程序的请求,必须验证其安全性。这样,应用程序就能知晓调用方是否有执行操作所需要的权限。 +SaaS 应用程序所作的任何事情,例如处理发送至应用程序的请求,必须验证其安全性。这样,应用程序就能知晓调用方是否有执行操作所需要的权限。 -在这里,通过 before-request 处理程序进行权限检查。这样,无论你使用处理请求的任何其他代码,你都已经拥有了会话信息。 +在这里,通过请求前处理程序进行权限检查。这样,无论其他代码如何处理请求,都已经掌握了会话信息。 -为保持会话数据(比如会话 ID 和用户 ID)在你代码中的任何地方都可用,你可以使用 **global_request_data**。它只是一个指向内存的通用指针(**void***),任何处理请求的代码都可以访问它。这非常适合处理会话,如下所示: +为保持会话数据(比如会话 ID 和用户 ID)在你代码中的任何地方都可用,你可以使用 `global_request_data`。它只是一个指向内存的通用指针(`void*`),任何处理请求的代码都可以访问它。这非常适合处理会话,如下所示: ``` #include "vely.h" #include "login.h" -// _before() 是 before-request-handler。它总是在任何其它处理请求的 -// 任何其它处理请求的代码之前执行。它是任何类型的 -// 请求范围设置或数据初始化的好地方 +// _before() 是一个请求前处理程序。 +// 它总是在处理请求的其他代码之前执行。 +// 对于任何类型的请求范围设置或数据初始化,它都是一个很好的位置。 void _before() {     // 输出 HTTP 请求头     out-header default @@ -303,16 +305,16 @@ void _before() {     // 将我们创建的数据设置为全局请求数据,     // 可以从任何处理请求的代码中访问     set-req data rd -    // 检查会话是否存在(基于来自客户端的 cookie) +    // 检查会话是否存在(基于来自客户端的 cookie)     // 这在任何其他请求处理代码之前执行,     // 使其更容易准备好会话信息     _check_session (); } ``` -#### 检查会话是否有效 (_check_session.vely) +#### 检查会话是否有效(_check_session.vely) -多租户 SaaS 应用程序中最重要的任务之一就是通过检查用户是否登录来检查(尽快)会话是否有效。这是通过从客户端(例如 web 浏览器)获取会话 ID 和用户 ID 的 cookie,并将它们与存储会话的数据库进行比较来实现的: +多租户 SaaS 应用程序中最重要的任务之一就是通过检查用户是否登录来(尽快)检查会话是否有效。这是通过从客户端(例如网络浏览器)获取会话 ID 和用户 ID 的 cookie,并将它们与存储会话的数据库进行比较来实现的: ``` #include "vely.h" @@ -328,7 +330,7 @@ void _check_session () {     get-cookie rd->sess_userId="sess_userId"     get-cookie rd->sess_id="sess_id"     if (rd->sess_id[0] != 0) { -        // 检查对于给定用户 ID 下的会话 ID 是否正确 +        // 检查给定用户 ID 下的会话 ID 是否正确         char *email;         run-query @db_multitenant_SaaS = "select email from users where userId='%s' and session='%s'" output email : rd->sess_userId, rd->sess_id row-count define rcount             query-result email to email @@ -346,19 +348,19 @@ void _check_session () { } ``` -#### 注册,登录,登出(login.vely) +#### 注册、登录、登出(login.vely) -T任何多租户系统的基础便是具有用户注册,登录和登出的功能。通常情况下,注册包括验证电子邮件地址;不止于此,同一电子邮件地址会作为一个用户名。这里有个例子。 +任何多租户系统的基础便是具有用户注册\登录和登出的功能。通常情况下,注册包括验证电子邮件地址;不止于此,同一电子邮件地址会作为一个用户名。这里就是这种情况。 这里实现了几个执行该功能所必须的子请求: -- 注册新用户时,显示 HTML 表单以收集信息。它的 URL 请求签名是`req=login&action=newuser`。 -- 作为对注册表单的响应,创建一个新用户。URL 请求的签名是`req=login&action=createuser`。**input-param** 信号获取 **email** 和 **pwd** 的 POST 表单字段。密码值是单向散列,电子邮件验证令牌是一个随机的 5 位数字。这些被插入到 **users** 表中,创建一个新用户。系统会发送一封验证邮件,并提示用户阅读邮件并输入代码。 -- 通过输入发送到该电子邮件的验证码来验证电子邮件。URL 请求的签名是`req=login&action=verify`。 -- 显示一个登录表单,让用户登录。URL 请求的签名是`req=login`(例如,`action`为空)。 -- 通过验证电子邮件地址(用户名)和密码登录。URL请求的签名是`req=login&action=login`。 -- 应用户要求登出。URL请求的签名是`req=login&action=logout`。 -- 应用程序的登录页。URL请求的签名是`req=login&action=begin`。 +- 注册新用户时,显示 HTML 表单以收集信息。它的 URL 请求签名是 `req=login&action=newuser`。 +- 作为对注册表单的响应,创建一个新用户。URL 请求的签名是 `req=login&action=createuser`。输入参数(`input-param`)信号获取 `email` 和 `pwd` 的 POST 表单字段。密码值是单向散列,电子邮件验证令牌是一个随机的 5 位数字。这些被插入到 `users` 表中,创建一个新用户。系统会发送一封验证邮件,并提示用户阅读邮件并输入代码。 +- 通过输入发送到该电子邮件的验证码来验证电子邮件。URL 请求的签名是 `req=login&action=verify`。 +- 显示一个登录表单,让用户登录。URL 请求的签名是 `req=login`(例如,`action` 为空)。 +- 通过验证电子邮件地址(用户名)和密码登录。URL 请求的签名是 `req=login&action=login`。 +- 应用户要求登出。URL 请求的签名是 `req=login&action=logout`。 +- 应用程序的登录页。URL 请求的签名是 `req=login&action=begin`。 - 如果用户当前已登录,转到应用程序的登录页面。 可以看看下面这些例子: @@ -367,10 +369,9 @@ T任何多租户系统的基础便是具有用户注册,登录和登出的功 #include "vely.h" #include "login.h" -// 处理任何云端多租户应用程序的会话维护,登录,注销,会话验证 -// 会话维护,登录,注销,会话验证 +// 处理云端多租户应用程序的会话维护、登录、注销、会话验证 void login () { -    // 获取 URL 的输入参数"action" +    // 获取 URL 的输入参数 `action`     input-param action     // 获取全局请求数据,我们在其中记录会话信息,所以它很方便 @@ -386,14 +387,14 @@ void login () {         }     } -    // 应用程序页面启动。 显示登录或注册的链接, +    // 应用程序页面启动。显示登录或注册的链接,     // 并显示适当的主屏幕     if (!strcmp (action, "begin")) {         _show_home();         exit-request -    // 开始创建新用户。 询问电子邮件和密码, -    // 然后在提交此表单时继续创建用户。 +    // 开始创建新用户。询问电子邮件和密码, +    // 然后提交此表单时创建用户。     } else if (!strcmp (action, "newuser")) {         @Create New User
        @
@@ -425,11 +426,11 @@ void login () {     } else if (!strcmp (action, "createuser")) {         input-param email         input-param pwd -        // 创建散列(单向)密码 +        // 创建散列(单向)密码         hash-string pwd to define hashed_pwd         // 生成随机的 5 位数字字符串验证代码         random-string to define verify length 5 number -        // 创建用户:插入电子邮件,哈希密码,验证令牌。当前验证状态为 0,或未验证 +        // 创建用户:插入电子邮件、哈希密码、验证令牌。当前验证状态为 0,或未验证         begin-transaction @db_multitenant_SaaS         run-query @db_multitenant_SaaS no-loop = "insert into users (email, hashed_pwd, verified, verify_token, session) values ('%s', '%s', '0', '%s', '')" : email, hashed_pwd, verify affected-rows define arows error define err on-error-continue         if (strcmp (err, "0") || arows != 1) { @@ -479,7 +480,7 @@ void login () {     } else if (!strcmp (action, "login")) {         input-param pwd         input-param email -        // 创建单向散列,目的是与用户表进行比较 —— 密码 永远不会 被记录 +        // 创建单向散列,目的是与用户表进行比较 —— 密码**永远不会**被记录         hash-string pwd to define hashed_pwd         // 为会话 ID 创建一个随机的 30 位长的字符串         random-string to rd->sess_id length 30 @@ -521,9 +522,9 @@ void login_or_signup() { } ``` -#### 通用应用程序 (_show_home.vely) +#### 通用应用程序(_show_home.vely) -借助本教程,您可以创建您想要的任何多租户 SaaS 应用程序。上面的多租户处理模块(`login.vely`)调用 **_show_home()** 函数,它可以容纳你的任何代码。这个示例代码展示了笔记应用程序,但它可以是任何内容。**_show_home()** 函数可以调用你想要的任何代码,它是一个通用的多租户应用程序插件: +借助本教程,你可以创建你想要的任何多租户 SaaS 应用程序。上面的多租户处理模块(`login.vely`)调用 `_show_home()` 函数,它可以容纳你的任何代码。这个示例代码展示了笔记应用程序,但它可以是任何内容。`_show_home()` 函数可以调用你想要的任何代码,它是一个通用的多租户应用程序插件: ``` #include "vely.h" @@ -536,7 +537,7 @@ void _show_home() { #### 笔记应用程序(notes.vely) -该应用程序能够添加,列举以及删除任何给定的笔记: +该应用程序能够添加、列举以及删除任何给定的笔记: ``` #include "vely.h" @@ -564,7 +565,7 @@ void notes () {     // 列举该用户的所有笔记     if (!strcmp (subreq, "list")) { -        // 只 选取该用户的笔记 +        // **只**选取该用户的笔记         run-query @db_multitenant_SaaS = "select dateOf, note, noteId from notes where userId='%s' order by dateOf desc" : rd->sess_userId output dateOf, note, noteId             query-result dateOf to define dateOf             query-result note to define note @@ -590,7 +591,7 @@ void notes () {         input-param note_id         // 删除笔记         run-query @db_multitenant_SaaS = "delete from notes where noteId='%s' and userId='%s'" : note_id, rd->sess_userId affected-rows define arows no-loop error define errnote -        // Inform user of status +        // 告知用户状态         if (arows == 1) {             @Note deleted         } else { @@ -600,7 +601,7 @@ void notes () {     // 添加笔记     else if (!strcmp (subreq, "add_note")) { -        // 从note表单中获取 URL POST 数据 +        // 从 note 表单中获取 URL POST 数据         input-param note         // 在该用户的 ID 下插入笔记         run-query @db_multitenant_SaaS = "insert into notes (dateOf, userId, note) values (now(), '%s', '%s')" : rd->sess_userId, note affected-rows define arows no-loop error define errnote @@ -612,7 +613,7 @@ void notes () {         }     } -    // 显示一个 HTML 表单来收集笔记,并将其发送回这里(使用 subreq="add_note" URL 参数) +    // 显示一个 HTML 表单来收集笔记,并将其发送回这里(使用 subreq="add_note" URL 参数)     else if (!strcmp (subreq, "add")) {         @Add New Note         @ @@ -626,7 +627,11 @@ void notes () { ### 具有 C 性能的 SaaS -Vely 语言使得 C 语言在你的 Web 应用程序中得到充分利用这件事成为可能。多租户 SaaS 应用程序便是从中受益的一个典型用例。参考参考代码示例,写一写代码,然后给 Vely 一个机会。 +Vely 语言使得 C 语言在你的网络应用程序中得到充分利用这件事成为可能。多租户 SaaS 应用程序便是从中受益的一个典型用例。 + +看一看参考代码示例,写一写代码,然后试试 Vely。 + +*(题图:DA/126624c8-1a47-481b-b149-92273e8e0f4f)* -------------------------------------------------------------------------------- @@ -634,8 +639,8 @@ via: https://opensource.com/article/22/11/build-your-own-saas-vely 作者:[Sergio Mijatovic][a] 选题:[lkxed][b] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[Drwhooooo](https://github.com/Drwhooooo) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -650,3 +655,4 @@ via: https://opensource.com/article/22/11/build-your-own-saas-vely [7]: https://opensource.com/sites/default/files/2022-10/6confirmdelete.png [8]: https://opensource.com/sites/default/files/2022-10/7notedeleted.png [9]: https://vely.dev/ +[0]: https://img.linux.net.cn/data/attachment/album/202312/12/110902myyfcm3hdmwqv3zy.jpg \ No newline at end of file