使用PostgREST构建PostgreSQL数据库的REST风格API

欢迎使用PostgREST!在本教程中,我们将使事情开始运行,以便您可以创建第一个简单的API。

PostgREST是一个独立的Web服务器,它将PostgreSQL数据库转换为RESTful API。它提供基于基础数据库的结构自定义的API。

为了制作一个API,我们将简单地建立一个数据库。所有端点和权限都来自数据库对象,例如表,视图,角色和存储过程。这些教程将涵盖许多常见方案以及如何在数据库中对其进行建模。

在本教程结束时,您将拥有一个正常运行的数据库,PostgREST服务器和一个简单的单用户待办事项列表API。

步骤1. 如何获取帮助

在开始本教程时,在另一个选项卡中弹出以打开项目聊天室。有很多人参与该项目,如果您遇到困难,我们会帮助您。

步骤2. 安装的PostgreSQL 

您将需要在系统上本地运行或在Docker实例中运行数据库的现代副本。我们要求PostgreSQL 9.3或更高版本,但建议至少使用9.5,以便在以后的教程中使用行级安全性功能。

如果您已经熟悉使用PostgreSQL并将其安装在系统上,则可以使用现有安装。在本教程中,我们将描述如何在Docker中使用数据库,因为对于一个简单的教程而言,数据库配置太复杂了。

如果未安装Docker,则可在此处获取。接下来,让我们拉起并启动数据库映像:

sudo docker run --name tutorial -p 5433:5432 \-e POSTGRES_PASSWORD=mysecretpassword \-d postgres

这会将Docker实例作为守护程序运行,并将端口5433暴露给主机系统,以便在系统的其余部分看起来像普通的PostgreSQL服务器。

步骤3. 安装PostgREST 

PostgREST以单个二进制文件的形式分发,其版本针对Linux / BSD / Windows的主要发行版进行了编译。访问最新版本以获取下载列表。如果您的平台不在预先构建的平台中,请参阅从源代码构建以获取有关如何自行构建平台的说明。还请告知我们在下一个版本中添加您的平台。

用于下载的预构建二进制文件是.tar.xz压缩文件(Windows是zip文件除外)。要提取二进制文件,请进入终端并运行

# download from https://github.com/PostgREST/postgrest/releases/latesttar xfJ postgrest-<version>-<platform>.tar.xz

结果将是一个简单命名的文件postgrest(或postgrest.exe在Windows上)。此时,请尝试使用

./postgrest

如果一切正常,它将打印出其版本和有关配置的信息。您可以从下载位置继续运行此二进制文件,也可以将其复制到/usr/local/binLinux上的系统目录中,以便可以从任何目录运行它。

注意

PostgREST要求在系统上安装libpq(PostgreSQL C库)。没有该库,您将收到类似“加载共享库时出错:libpq.so.5”之类的错误。这是解决方法:

Ubuntu或Debian

Fedora,CentOS或Red Hat

OS X

Windows

步骤4. 为API创建数据库

连接到容器内的SQL控制台(psql)。为此,请从命令行运行此命令:

sudo docker exec -it tutorial psql -U postgres

您应该看到psql命令提示符:

psql (9.6.3)
Type "help" for help.postgres=#

我们要做的第一件事是为将在API中公开的数据库对象创建一个命名模式。我们可以选择任何喜欢的名称,然后选择“ api”。执行此操作,并在启动的psql提示中执行其他SQL语句。

create schema api;

我们的API将有一个终结点,/todos该终结点来自一个表。

create table api.todos (id serial primary key,done boolean not null default false,task text not null,due timestamptz
);insert into api.todos (task) values('finish tutorial 0'), ('pat self on back');

接下来,创建一个角色以用于匿名Web请求。收到请求时,PostgREST将切换到数据库中的该角色以运行查询。

create role web_anon nologin;grant usage on schema api to web_anon;
grant select on api.todos to web_anon;

web_anon角色有权访问api架构中的内容,并有权读取todos表中的行。

创建专用角色以连接到数据库是一种好习惯,而不是使用特权较高的postgres角色。因此,我们将执行此操作,命名角色authenticator,并授予他切换到该web_anon角色的能力:

create role authenticator noinherit login password 'mysecretpassword';
grant web_anon to authenticator;

现在退出psql;是时候启动API了!

\q

步骤5.运行PostgREST 

PostgREST使用配置文件来告诉它如何连接到数据库。在其中创建一个文件tutorial.conf

db-uri = "postgres://authenticator:mysecretpassword@localhost:5433/postgres"
db-schema = "api"
db-anon-role = "web_anon"

配置文件还有其他选项,但这就是我们所需要的。现在运行服务器:

./postgrest tutorial.conf

你应该看到

Listening on port 3000
Attempting to connect to the database...
Connection successful

现在可以处理网络请求了。您可以使用许多不错的图形API探索工具,但是在本教程中,我们将使用curl它,因为它可能已经安装在您的系统上。打开一个新终端(保留其中一个正在运行PostgREST的终端)。尝试对待办事项执行HTTP请求。

curl http://localhost:3000/todos

API回复:

[{"id": 1,"done": false,"task": "finish tutorial 0","due": null},{"id": 2,"done": false,"task": "pat self on back","due": null}
]

使用当前角色权限,匿名请求对todos表具有只读访问权限。如果我们尝试添加新的待办事项,我们将无法执行。

curl http://localhost:3000/todos -X POST \-H "Content-Type: application/json" \-d '{"task": "do bad thing"}'

响应为401未经授权:

{"hint": null,"details": null,"code": "42501","message": "permission denied for relation todos"
}

我们已经有了它,数据库之上的基本API!在接下来的教程中,我们将看到如何使用更复杂的用户访问控制以及更多的表和查询来扩展示例。

现在您已经运行了PostgREST。

在上述教程中,我们创建了一个带有单个端点的只读API以列出待办事项。我们可以采取许多方法来使该API更加有趣,但是一个不错的起点是允许一些用户在读取数据的同时更改数据。

步骤6. 添加受信任的用户

上一教程web_anon在数据库中创建了一个角色,用于执行匿名Web请求。让我们todo_user为使用API​​进行身份验证的用户创建一个角色。该角色将有权对待办事项列表做任何事情。

-- run this in psql using the database created
-- in the previous tutorialcreate role todo_user nologin;
grant todo_user to authenticator;grant usage on schema api to todo_user;
grant all on api.todos to todo_user;
grant usage, select on sequence api.todos_id_seq to todo_user;

步骤7. 加密令牌

客户端使用JSON Web令牌向API进行身份验证。这些是JSON对象,使用仅我们和服务器已知的密码进行加密签名。因为客户端不知道密码,所以他们无法篡改其令牌的内容。PostgREST将检测伪造令牌并拒绝它们。

让我们创建一个密码并将其提供给PostgREST。想想一个不错的长篇文章,或使用一种工具生成它。您的密码必须至少包含32个字符。

注意

Unix工具可以为您生成一个不错的密码:

# Allow "tr" to process non-utf8 byte sequences
export LC_CTYPE=C# read random bytes and keep only alphanumerics
< /dev/urandom tr -dc A-Za-z0-9 | head -c32

打开tutorial.conf(在上一教程中创建的)并添加带有密码的行:

# PASSWORD MUST BE AT LEAST 32 CHARS LONG
# add this line to tutorial.conf:jwt-secret = "<the password you made>"

如果PostgREST服务器仍在上一教程中运行,请重新启动它以加载更新的配置文件。

步骤8. 签署令牌

通常,您在数据库或另一台服务器中的自己的代码将创建并签名身份验证令牌,但是对于本教程,我们将“手工制作”一个。转到jwt.io并填写如下字段:

如何在https://jwt.io创建令牌

请记住填写您生成的密码,而不要输入“ secret”。填写密码和有效载荷后,左侧的编码数据将更新。复制编码的令牌。

注意

尽管令牌看起来很模糊,但对负载进行反向工程很容易。令牌只是签名的,没有加密的,所以不要把东西放进不想让确定的客户看到的东西。

步骤9. 发出请求

回到终端,让我们使用curl添加待办事项。该请求将包含一个包含身份验证令牌的HTTP标头。

export TOKEN="<paste token here>"curl http://localhost:3000/todos -X POST \-H "Authorization: Bearer $TOKEN"   \-H "Content-Type: application/json" \-d '{"task": "learn how to auth"}'

现在,我们已经完成了待办事项列表中的所有三个项目,因此让我们将done所有PATCH请求都设置为true 。

curl http://localhost:3000/todos -X PATCH \-H "Authorization: Bearer $TOKEN"    \-H "Content-Type: application/json"  \-d '{"done": true}'

待办事项的请求显示了其中三个,并且都已完成。

curl http://localhost:3000/todos

[{"id": 1,"done": true,"task": "finish tutorial 0","due": null},{"id": 2,"done": true,"task": "pat self on back","due": null},{"id": 3,"done": true,"task": "learn how to auth","due": null}
]

步骤10. 添加到期时间

目前,我们的身份验证令牌对所有永恒有效。只要服务器继续使用相同的JWT密码,服务器就会使用该令牌。

更好的策略是使用声明包含令牌的过期时间戳exp。这是PostgREST特别对待的两个JWT主张之一。

要求 解释
role 在数据库角色下执行SQL请求API
exp 令牌的过期时间戳,以“ Unix epoch time”表示

注意

纪元时间定义为自1970年1月1日00:00:00协调世界时(UTC)起经过的秒数,减去此后发生的of秒数。

为了观察有效期,我们将exp在未来的令牌中添加五分钟的索赔。首先找到从现在起五分钟的纪元值。在psql中运行以下命令:

select extract(epoch from now() + '5 minutes'::interval) :: integer;

返回jwt.io并将有效负载更改为

{"role": "todo_user","exp": 123456789
}

注意:不要忘记将123456789以上代码段中的虚拟纪元值更改为psql命令返回的纪元值。

像以前一样复制更新的令牌,并将其另存为新的环境变量。

export NEW_TOKEN="<paste new token>"

尝试在到期之前和之后以curl发出此请求:

curl http://localhost:3000/todos \-H "Authorization: Bearer $NEW_TOKEN"

到期后,API返回未经授权的HTTP 401:

{"message":"JWT expired"}

撤销令牌

即使令牌过期,有时您还是可能想立即撤消对特定令牌的访问。例如,假设您了解到一个心怀不满的员工无济于事,而他的令牌仍然有效。

要撤销特定令牌,我们需要一种区别于其他令牌的方法。让我们添加一个email与发出该令牌的客户端电子邮件匹配的自定义声明。

继续并使用有效载荷制作新令牌

{"role": "todo_user","email": "disgruntled@mycompany.com"
}

将其保存到环境变量:

export WAYWARD_TOKEN="<paste new token>"

PostgREST允许我们指定在尝试身份验证期间运行的存储过程。该函数可以执行其喜欢的任何事情,包括引发异常以终止请求。

首先创建一个新的架构并添加函数:

create schema auth;
grant usage on schema auth to web_anon, todo_user;create or replace function auth.check_token() returns voidlanguage plpgsqlas $$
beginif current_setting('request.jwt.claim.email', true) ='disgruntled@mycompany.com' thenraise insufficient_privilegeusing hint = 'Nope, we are on to you';end if;
end
$$;

下次更新tutorial.conf并指定新功能:

# add this line to tutorial.confpre-request = "auth.check_token"

重新启动PostgREST,以使更改生效。接下来,尝试使用我们的原始令牌提出请求,然后使用已撤销的令牌进行请求。

# this request still workscurl http://localhost:3000/todos -X PATCH \-H "Authorization: Bearer $TOKEN"    \-H "Content-Type: application/json"  \-d '{"done": true}'# this one is rejectedcurl http://localhost:3000/todos -X PATCH      \-H "Authorization: Bearer $WAYWARD_TOKEN" \-H "Content-Type: application/json"       \-d '{"task": "AAAHHHH!", "done": false}'

服务器以403禁止响应:

{"hint": "Nope, we are on to you","details": null,"code": "42501","message": "insufficient_privilege"
}

使用PostgREST构建PostgreSQL数据库的REST风格API相关推荐

  1. 使用PostgREST的RestAPI操作PostgreSQL数据库教程

    使用PostgREST的RestAPI操作PostgreSQL数据库教程 表和视图 公开的架构中的所有视图和表均可被查询的活动数据库角色访问,并且可供活动数据库角色访问.它们暴露在一级深度路线中.例如 ...

  2. typescript-koa-postgresql 实现一个简单的rest风格服务器 —— 连接 postgresql 数据库...

    接上一篇,这里使用 sequelize 来连接 postgresql 数据库 1.安装 sequelize,数据库驱动 pg yarn add sequelize sequelize-typescri ...

  3. Spring Boot中使用PostgreSQL数据库

    在如今的关系型数据库中,有两个开源产品是你必须知道的.其中一个是MySQL,相信关注我的小伙伴们一定都不陌生,因为之前的Spring Boot关于关系型数据库的所有例子都是对MySQL来介绍的.而今天 ...

  4. Serverless 解惑——函数计算如何访问 PostgreSQL 数据库

    函数计算(Function Compute):函数计算 是事件驱动的全托管计算服务.使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码.函数计算为您准备好计算资源,弹性地可靠地运行任务 ...

  5. eclipse连接mysql_专题一、flask构建mysql数据库正确姿势

    每周壹总结,一起共同充电第121篇 应用程序最核心的就是数据,每天我们写程序其实也是在处理数据的过程,那么很有必要系统性的讲讲和梳理python的flask框架是如何进行数据交互操作的. 趁这3天假期 ...

  6. oracle rds 运维服务_从运维的角度分析使用阿里云数据库RDS的必要性–你不应该在阿里云上使用自建的MySQL/SQL Server/Oracle/PostgreSQL数据库...

    开宗明义,你不应该在阿里云上使用自建的MySQL or SQL Server数据库,对了,还有Oracle or PostgreSQL数据库. 云数据库 RDS(Relational Database ...

  7. 函数计算如何访问 PostgreSQL 数据库

    函数计算(Function Compute):函数计算 是事件驱动的全托管计算服务.使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码.函数计算为您准备好计算资源,弹性地可靠地运行任务 ...

  8. 将PostgreSQL数据库扩展到每个月12亿条记录的经验教训

    这不是我第一次使用大型数据集.我为最大的英国公共Wi-Fi供应商设计的认证和产品管理数据库也有巨大的容量.我们每天跟踪数百万设备的身份认证.然而,该项目有资金,允许我们选择任何硬件.任何支持服务以及聘 ...

  9. OpenShift 4 - 使用 Debezium 捕获变化数据,实现MySQL到PostgreSQL数据库同步(附视频)

    <OpenShift / RHEL / DevSecOps 汇总目录> 说明:本文已经在OpenShift 4.10环境中验证 文章目录 场景说明 部署环境 安装CDC源和目标数据库 安装 ...

最新文章

  1. 用c语言编写心里测试,求各位大神赐教!我做了一个“心理测试的答题卷”编程,总共有1...
  2. 在Ubuntu下进行安卓开发遇到“insufficient permissions for device: user in plugdev group; ”问题的解决办法
  3. 010_JMS消息选择器
  4. 使用CSS3各个属性实现小人的动画
  5. 如何理解java中String的不可变性
  6. 内联函数和编译器对Go代码的优化
  7. Ж孤云Ж真的很适合我
  8. Cookie、token、session的区别是什么?
  9. 垃圾回收 | Java垃圾回收,这杯咖啡,不仅好喝,而且实用!
  10. sass import 小记
  11. 课程《设计模式之美》笔记之关于java四大特性
  12. 剑指Offer_42_和为S的两个数字
  13. crt怎么退出编辑模式_securecrt怎么退出当前指令
  14. matlab containers,matlab中的containers.Map()
  15. 文档安全有个服务器的组,云服务器安全组是什么意思
  16. 2022爱分析・智慧园区厂商全景报告 | 爱分析报告
  17. base64加密和解密(动态密钥)
  18. Java+Uiautomator自动化测试 -- 3.实现手机的五种解锁方式(无/滑动/图案/PIN码/密码|)
  19. 2019年最新《Web 前端开发》等级考试模拟题~以国家 “1+X” 职业技能证书为标准,厚溥推出 Web 前端开发人才培养方案...
  20. 四六级重要单词(三)

热门文章

  1. 检查xml文件中包含非法xml字符的个数(
  2. NYMEX ACCESS电子交易系统来
  3. jQuery获取div的背景颜色 How to get background color of div?
  4. 面向普通人的 PHP 加密
  5. 关闭Wordpress修订功能,清除“Revision”的方法
  6. jQuery 页面载入进度条 (必有一款适合你----综合搜集版)
  7. 多线程的第三种模式(callable)
  8. redis——redis持久化处理
  9. 【转载】vim常用命令总结
  10. 【AI 顶会】NIPS2019接收论文完整列表