淘先锋技术网

首页 1 2 3 4 5 6 7

起因

因为项目需求,需要学习PostgreSQL,本人之前学习过MYSQL,临时快速上手,尽快的去学习项目需要PostgREST, 在学习PostgREST的第一个起步案例 教程 0 - 让它运行起来 的时候碰到了下面几条语句:

CREATE ROLE web_anon NOLOGIN;

GRANT USAGE ON SCHEMA api TO web_anon;
GRANT SELECT ON api.todos TO web_anon;

因为不太懂PostgSQL,就行了了研究,研究结果如下:

第一个语句:

CREATE ROLE web_anon NOLOGIN;

这条命令创建了一个名为 web_anon 的新角色,并通过使用 NOLOGIN 选项指定该角色不能直接登录到数据库。通常,这是为了给不需要直接访问数据库的应用或服务授予权限。

第二个和第三个语句:

GRANT USAGE ON SCHEMA api TO web_anon;
GRANT SELECT ON api.todos TO web_anon;

这两条命令分别将对 schema api 的使用权(USAGE)和对表 api.todos 的查看权(SELECT)授予 web_anon 角色。这意味着任何具有 web_anon 角色的用户或连接将能够查询 api.todos 表中的数据。


如果不给USAGE,只给SELECT 会有什么效果

如果只授予角色(例如 web_anon)对表(如 api.todos)的 SELECT 权限但没有授予 SCHEMA(如 api)的 USAGE 权限,那么该角色将只能查询与授权的表相关的数据。

在这种情况下,web_anon 角色将仍然能够执行 SELECT 查询访问 api.todos 表中的数据,因为你已经授予了该角色针对该表的 SELECT 权限。然而,如果 schema api 包含其他对象(如数据类型、操作符、函数等),web_anon 角色将无法使用这些对象,因为没有授予 SCHEMA 的 USAGE 权限。

简而言之,没有 SCHEMA 的 USAGE 权限,角色将无法使用此 SCHEMA 中的其他数据库对象,但仍然可以运行 SELECT 查询以访问已授权表中的数据。需要注意的是,这可能会导致某些查询和操作失败,特别是当查询涉及到 SCHEMA 中其他对象时。

授权USAGE之后,还需要授权select 吗? 如果不授权select能进行查询数据吗?

即使已经授予角色 SCHEMA 的 USAGE 权限,你仍然需要为某个表(例如:api.todos)单独授权 SELECT 权限。USAGE 权限只让角色能够访问 SCHEMA 中的数据类型、操作符、函数等其他数据库对象,但是不包含对 SCHEMA 中的表的访问权。

如果没有为表(例如:api.todos)授权 SELECT 权限,即使已授权 SCHEMA 的 USAGE 权限,角色仍然无法读取该表中的数据。为了允许一个角色执行 SELECT 查询并获取某个表中的数据,你需要为该角色分别授权 SCHEMA 的 USAGE 权限和表的 SELECT 权限。

只有USAGE没有SELECT的例子

为了更好地理解只有 SCHEMA 的 USAGE 权限的情况,我们首先需要了解 PostgreSQL schema。一个 schema 是一个命名空间,它可以包含多个数据库对象,如表、视图、数据类型、函数等。在这个例子中,假设我们有一个名为 api 的 schema 和一个名为 api.todos 的表。我们还有一个自定义数据类型和一个函数。

创建自定义数据类型:

CREATE TYPE api.priority_level AS ENUM ('Low', 'Medium', 'High');

创建一个使用自定义数据类型的表:

CREATE TABLE api.todos_with_priority (
    id SERIAL PRIMARY KEY,
    task VARCHAR(255) NOT NULL,
    priority api.priority_level NOT NULL
);

创建一个使用自定义数据类型的函数:

CREATE FUNCTION api.get_priority_as_text(p api.priority_level) RETURNS text
    LANGUAGE sql
    AS $$ SELECT 'Priority: ' || p::text; $$;

如果我们创建一个名为 web_anon 的角色并仅授权 SCHEMA 的 USAGE 权限:

CREATE ROLE web_anon NOLOGIN;
GRANT USAGE ON SCHEMA api TO web_anon;

在这种情况下,web_anon 角色将可以使用 api schema 中的自定义数据类型(例如 api.priority_level)以及自定义函数(例如 api.get_priority_as_text),但由于缺少 SELECT 权限,它无法查询 api.todos_with_priority 表。

如果将 web_anon 角色分配给另一个用户或角色并尝试执行以下查询:

SELECT id, task, api.get_priority_as_text(priority)
FROM api.todos_with_priority;

这个查询将失败,因为没有授予 SELECT 权限。

为了让 web_anon 角色能查询 api.todos_with_priority 表,我们需要给它授予对该表的 SELECT 权限:

GRANT SELECT ON api.todos_with_priority TO web_anon;

总结

本文主要讨论了 PostgreSQL 中角色权限的授予及其影响。CREATE ROLE 命令用于创建一个新的角色,同时可以通过 NOLOGIN 选项指定角色无法直接登录到数据库。通过 GRANT 命令可以为角色授予权限,如 SCHEMA 的 USAGE 权限和对表的 SELECT 权限。

在授权过程中,注意区分 SCHEMA 的 USAGE 权限和表的 SELECT 权限。授予角色 SCHEMA 的 USAGE 权限意味着角色可以访问 SCHEMA 中的其他数据库对象(例如数据类型、操作符和函数等)。而为角色授予对表的 SELECT 权限,则允许角色查询该表的数据。

总之,在 PostgreSQL 中设置权限时,需要根据具体情况为角色分别授予 SCHEMA 的 USAGE 权限和表的 SELECT 权限,以确保正确的访问能力。仅具有 SCHEMA 的 USAGE 权限将无法访问表的数据,需要额外为表授予 SELECT 权限。